subroutine da_trace_entry(&
Name, & ! in
Message, & ! in, optional
Messages, & ! in, optional
MaxNoCalls) ! in, optional
!-----------------------------------------------------------------------
! Purpose: Trace entry point to subroutine
!-----------------------------------------------------------------------
implicit none
character (len=*), intent(in) :: Name ! Routine name
character (len=*), optional, intent(in) :: Message ! message
character (len=*), optional, intent(in) :: Messages(:) ! message array
integer, optional, intent(in) :: MaxNoCalls ! max no calls to show
integer :: IOStatus ! I-O return code
integer :: Loop ! General loop counter
integer :: Count
integer :: OldPointer
integer :: TotalSpace
integer :: LocalMaxNoCalls
real :: CPUTime1
real :: temp1
real :: temp2
logical :: NewRoutine
call cpu_time(CPUTime1)
call system_clock(&
COUNT=Count)
!-----------------------------------------------------------------------
! check if tracing active. If not check whether to switch it on
!-----------------------------------------------------------------------
if (.NOT. TraceActive) then
if (trace_start_points == 0) then
! start with first call
TraceActive = .true.
else
do Loop=1,trace_start_points
if (Name == TraceNames(Loop)(1:LEN(Name))) then
TraceActive = .true.
TraceDepth = 0
TraceStartedBy = Name
exit
end if
end do
end if
if (.NOT. TraceActive) then
! did not want to start trace, so leave
return
end if
end if
!-----------------------------------------------------------------------
! timing and maximum heap usage
!-----------------------------------------------------------------------
! Increment the local elapsed time and local CPU time since the
! last trace entry, if any
if (Pointer /= 0) then
temp1 = real(Count - BaseElapsedTime) - ElapsedTimeLocalStart
temp2 = CPUTime1 - CPUTimeLocalStart
ElapsedTimeLocal(Pointer) = ElapsedTimeLocal(Pointer) + temp1
ElapsedTimeThisCall(Pointer) = ElapsedTimeThisCall(Pointer) + temp1
CPUTimeLocal(Pointer) = CPUTimeLocal(Pointer) + temp2
CPUTimeThisCall(Pointer) = CPUTimeThisCall(Pointer) + temp2
end if
OldPointer=Pointer
! Check subroutine name
NewRoutine = .true.
do Pointer=1,NoRoutines
if (TimerNames(Pointer) == Name) then
NewRoutine=.false.
exit
end if
end do
if (NewRoutine) then
! New subroutine entered
if (NoRoutines >= MaxNoRoutines)then ! too many to trace
call da_error(__FILE__,__LINE__, &
(/"Too many routines. Not timing " // Name/))
!All the timings etc are put instead to the calling routine,
! which therefore may have incorrect summaries.
!The best solution is to increase MaxNoRoutines.
Pointer = OldPointer
! Fix to get the correct NoCalls(OldPointer) despite the +1 later
NoCalls(Pointer)=NoCalls(Pointer)-1
else ! Pointer=NoRoutines+1 (from the end of earlier do loop)
NoRoutines=NoRoutines+1
TimerNames(NoRoutines)=Name
end if
end if
NoCalls(Pointer)=NoCalls(Pointer)+1
CPUTimeThisCall(Pointer) = 0.0
ElapsedTimeThisCall(Pointer) = 0.0
CalledBy(Pointer)=OldPointer
if (trace_memory) then
call da_memory(&
TotalSpace)
EntryHeap(Pointer) = TotalSpace
LastSpace = TotalSpace
if (MaxHeap(Pointer) < TotalSpace) then
MaxHeap(Pointer) = TotalSpace
end if
else
TotalSpace = 0
end if
if (trace_write .AND. TraceDepth <= trace_max_depth) then
if (present(MaxNoCalls)) then
LocalMaxNoCalls = MaxNoCalls
else
LocalMaxNoCalls = trace_repeat_head
end if
if (NoCalls(Pointer) <= LocalMaxNoCalls) then
if (trace_memory) then
if (use_html) then
write (unit=trace_unit, &
fmt='(A,"> ",A,"",I11)', &
iostat=IOStatus) &
pad(1:TraceDepth*TraceIndentAmount),trim(Documentation_url), &
trim(Name),trim(Name), TotalSpace
else
write (unit=trace_unit, &
fmt='(A,"> ",A,I11)', &
iostat=IOStatus) &
pad(1:TraceDepth*TraceIndentAmount),trim(Name), TotalSpace
end if
else
if (use_html) then
write (unit=trace_unit, &
fmt='(A,"> ",A,"")', &
iostat=IOStatus) &
pad(1:TraceDepth*TraceIndentAmount),trim(Documentation_url), &
trim(Name),trim(Name)
else
write (unit=trace_unit, fmt='(A,"> ",A)', iostat=IOStatus) &
pad(1:TraceDepth*TraceIndentAmount),trim(Name)
end if
end if
if (IOStatus /= 0) then
call da_error(__FILE__,__LINE__, &
(/"Cannot write to trace file for "//Name/))
end if
if (present(Message)) then
write (unit=trace_unit, fmt='(A," ",A)', iostat=IOStatus) &
pad(1:TraceDepth*TraceIndentAmount),trim(Message)
if (IOStatus .NE. 0) then
call da_error(__FILE__,__LINE__, &
(/"Cannot write to trace file for "//Name/))
end if
end if
if (present(Messages)) then
do Loop = 1, size(Messages)
write (unit=trace_unit, fmt='(A," ",A)', iostat=IOStatus) &
pad(1:TraceDepth*TraceIndentAmount),trim(Messages(Loop))
if (IOStatus .NE. 0) then
call da_error(__FILE__,__LINE__, &
(/"Cannot write to trace file for "//Name/))
end if
end do ! Loop
end if
end if
end if ! trace_write
TraceDepth=TraceDepth+1
call system_clock(&
COUNT=Count)
call cpu_time(CPUTime1)
! set the start elapsed and CPU time both locally and generally
ElapsedTimeStart(Pointer) = real(Count-BaseElapsedTime)
ElapsedTimeLocalStart = real(Count-BaseElapsedTime)
CPUTimeStart(Pointer) = CPUTime1
CPUTimeLocalStart = CPUTime1
! call flush(trace_unit)
return
end subroutine da_trace_entry