subroutine timer(dname,k) ! Times procedure number n between a call with k=0 (tstart) and with ! k=1 (tstop). Accumulates sums of these times in array ut (user time). ! Also traces all calls (for debugging purposes) if limtrace.gt.0 !$ interface !$ integer function omp_get_thread_num() !$ end function !$ end interface character*8 dname !$ character thread character*11 tname,ename character*16 sname character*11, save :: space integer, save :: level, nmax character*11, save :: name(50) logical, save :: on(50) real, save :: ut(50),ut0(50),dut(50) integer, save :: ncall(50),nlevel(50),nparent(50) integer, save :: onlevel(0:10) common/tracer/ limtrace,lu data eps/0.000001/,ntrace/0/ data level/0/,nmax/0/,space/' '/ data limtrace/0/,lu/-1/ !$omp threadprivate(level,space,onlevel) tname=dname !$ write(thread,'(i1)') omp_get_thread_num() !$ tname=trim(dname)//'('//thread//')' ! decorate name with thread number !$omp critical(timer) if(limtrace.lt.0) go to 999 if(lu.lt.1) lu=6 if(k.gt.1) go to 40 !Check for "all done" (k>1) onlevel(0)=0 do n=1,nmax !Check for existing name if(name(n).eq.tname) go to 20 enddo nmax=nmax+1 !This is a new one n=nmax ncall(n)=0 on(n)=.false. ut(n)=eps name(n)=tname 20 if(k.eq.0) then !Get start times (k=0) if(on(n)) print*,'Error in timer: ',tname,' already on.' level=level+1 !Increment the level on(n)=.true. ! call system_clock(icount,irate) ! ut0(n)=float(icount)/irate ! call cpu_time(ut0(n)) ut0(n)=secnds(0.0) ncall(n)=ncall(n)+1 if(ncall(n).gt.1.and.nlevel(n).ne.level) then nlevel(n)=-1 else nlevel(n)=level endif nparent(n)=onlevel(level-1) onlevel(level)=n else if(k.eq.1) then !Get stop times and accumulate sums. (k=1) if(on(n)) then on(n)=.false. ! call system_clock(icount,irate) ! ut1=float(icount)/irate ! call cpu_time(ut1) ut1=secnds(0.0) ut(n)=ut(n)+ut1-ut0(n) endif level=level-1 endif ntrace=ntrace+1 if(ntrace.lt.limtrace) write(lu,1020) ntrace,tname,k,level,nparent(n) 1020 format(i8,': ',a11,3i5) go to 998 ! Write out the timer statistics 40 write(lu,1040) 1040 format(/' name time frac dtime', & ' dfrac calls level parent'/73('-')) if(k.gt.100) then ndiv=k-100 do i=1,nmax ncall(i)=ncall(i)/ndiv ut(i)=ut(i)/ndiv enddo endif total=ut(1) sum=0. sumf=0. do i=1,nmax dut(i)=ut(i) do j=i,nmax if(nparent(j).eq.i) dut(i)=dut(i)-ut(j) enddo if(dut(i).lt.0.0) dut(i)=0.0 utf=ut(i)/total dutf=dut(i)/total sum=sum+dut(i) sumf=sumf+dutf kk=nlevel(i) sname=space(1:kk)//name(i)//space(1:11-kk) ename=space if(nparent(i).ge.1) ename=name(nparent(i)) write(lu,1060) float(i),sname,ut(i),utf,dut(i),dutf, & ncall(i),nlevel(i),ename 1060 format(f4.0,a16,2(f10.3,f6.2),i7,i5,2x,a11) enddo write(lu,1070) sum,sumf 1070 format(/36x,f10.2,f6.2) nmax=0 eps=0.000001 ntrace=0 level=0 space=' ' onlevel(0)=0 998 flush(lu) 999 continue !$omp end critical(timer) return end subroutine timer