File: timer_data.F

package info (click to toggle)
aces3 3.0.6-7
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 82,460 kB
  • sloc: fortran: 225,647; ansic: 20,413; cpp: 4,349; makefile: 953; sh: 137
file content (252 lines) | stat: -rw-r--r-- 9,222 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
C  Copyright (c) 2003-2010 University of Florida
C
C  This program is free software; you can redistribute it and/or modify
C  it under the terms of the GNU General Public License as published by
C  the Free Software Foundation; either version 2 of the License, or
C  (at your option) any later version.

C  This program is distributed in the hope that it will be useful,
C  but WITHOUT ANY WARRANTY; without even the implied warranty of
C  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
C  GNU General Public License for more details.

C  The GNU General Public License is included in this distribution
C  in the file COPYRIGHT.
      subroutine tmanal(siofile, io_company_id)
c----------------------------------------------------------------------------
c   Gathers timer data from all servers and workers.  If the ACES_SOURCE_DIR
c   environment variable is set, the routine searches for a SIAL source 
c   file with the correct name, and produces a source-level timing analysis
c   of the gathered data.
c---------------------------------------------------------------------------
      implicit none
      include 'mpif.h'
      include 'proto_defines.h'
      include 'proto_events.h'
      include 'timerz.h'
      include 'machine_types.h'
      include 'parallel_info.h'
#ifdef ALTIX
       include 'sheap.h'
#endif

      integer io_company_id
      character*(*) siofile

      integer i, j, nprocs_save, ierr
      integer*8 irecv
      integer*8 itimer, itstat, idesc, idesc_scr
      integer*8 itimer_avg, itimer_sd
      integer status_mpi(MPI_STATUS_SIZE), status, nints
      integer request_status(mpi_status_size,2*nprocs)
      integer timer_request(2*nprocs)
      double precision timer_stats(1) 
      integer timer_descs(1) 

      integer itdesc(1)
      equivalence (itdesc(1), tdesc(1))

      integer nw
      integer*8 c_loc64

      integer pst_get_role
#ifdef HP
      integer*8 lenshmem
#else
      integer lenshmem
#endif

#ifdef ALTIX
      pointer (iptr, timer_descs)
      pointer (dptr, timer_stats)

      iptr = ishptr
      dptr =dshptr
#else
      common timer_stats, timer_descs
#endif

c--------------------------------------------------------------------------
c   Collect the server stats, and print a summary.
c--------------------------------------------------------------------------

      call print_server_data(io_company_id)

      if (.not. do_timer) return

      nprocs_save = nprocs

c--------------------------------------------------------------------------
c   Set up the timer statistic buffer.
c--------------------------------------------------------------------------

      nw = 4*max_timers
      call mem_alloc(timer_stats, nw, bytes_per_double, itstat,
     *                .true., ierr)
      if (ierr .ne. 0) then
         print *,'Cannot alloc timer memory: itstat nw ',nw
         call abort_job()
      endif
 
      nw = max_timers
      call mem_alloc(timer_stats, nw, bytes_per_double, itimer_avg,
     *               .true., ierr)
      if (ierr .ne. 0) then
         print *,'Cannot alloc timer memory: itimer_avg nw ',nw
         call abort_job()
      endif
 
      call mem_alloc(timer_stats, nw, bytes_per_double, itimer_sd,
     *               .true., ierr)
      if (ierr .ne. 0) then
         print *,'Cannot alloc timer memory: itimer_sd nw ',nw
         call abort_job()
      endif

      nints = (max_timers*max_timer_desc_len+intsize-1)/intsize
      nw = 2*nints
      call mem_alloc(timer_descs, nw, intsize, idesc,
     *               .true., ierr)
      if (ierr .ne. 0) then
         print *,'Cannot alloc timer memory: idesc nw ',nw
         call abort_job()
      endif
      
c--------------------------------------------------------------------------
c   Initialize the sum, avg, and sd buffers.
c--------------------------------------------------------------------------

      call sum_timer_data(timer_stats(itstat), 
     *                    timers,
     *                    timer_descs(idesc),             
     *                    itdesc,
     *                    timer_stats(itimer_avg),
     *                    timer_stats(itimer_sd), max_timers,
     *                    max_timer_desc_len, .true.) 

c--------------------------------------------------------------------------
c   Post a recv for each contraction worker and integral worker in which
c   to receive the timer statistics for the workers.
c
c   These recv's will not complete until each process sends the master its
c   timer data at termination time.
c--------------------------------------------------------------------------

      do i = 2, nprocs
         status = pst_get_role(i-1)
         if (status .eq. worker_status .or.
     *       status .eq. both_status .or.
     *       status .eq. master_worker_status) then

c--------------------------------------------------------------------------
c   Receive the timer data from proc i-1.
c--------------------------------------------------------------------------

            itimer = itstat + 3*max_timers
            call mpi_recv(timer_stats(itimer), max_timers,
     *               mpi_double_precision, (i-1),
     *               timer_data_request_tag, mpi_comm_world,
     *               status_mpi, ierr)

c--------------------------------------------------------------------------
c   Receive the timer descriptor data from proc i-1.
c--------------------------------------------------------------------------

            irecv = nints + idesc   
            call mpi_recv(timer_descs(irecv), nints,
     *                  mpi_integer, (i-1),
     *                  timer_desc_request_tag, mpi_comm_world,
     *                  status_mpi, ierr)

            call sum_timer_data(timer_stats(itstat), 
     *                          timer_stats(itstat+3*max_timers),
     *                          timer_descs(idesc),             
     *                          timer_descs(idesc+nints),
     *                          timer_stats(itimer_avg),
     *                          timer_stats(itimer_sd), max_timers,
     *                          max_timer_desc_len, .false.) 
         endif
      enddo

c----------------------------------------------------------------------------
c   Print the timer data.
c----------------------------------------------------------------------------

      call timer_report(siofile, timer_descs(idesc), 
     *          timer_stats(itstat), 
     *          timer_stats(itimer_avg),
     *          timer_stats(itimer_sd),
     *          nprocs_save)

      return
      end

      subroutine sum_timer_data(sumdata, instance, descs, 
     *                          descs_instance, contrib, sumsq,
     *                          max_timers, max_timer_desc_len,
     *                          init)  
c---------------------------------------------------------------------------
c   Sums the timer data from one processor (instance) into the total sum 
c   buffer.  The number of contributing elements and the sum of squares 
c   for each timer is also accumulated.
c---------------------------------------------------------------------------
      
      implicit none
      integer i, j
      integer max_timers
      integer max_timer_desc_len
      double precision sumdata(max_timers,3), instance(max_timers)
      double precision sumsq(max_timers), contrib(max_timers)
      character*(max_timer_desc_len) descs(max_timers)
      character*(max_timer_desc_len) descs_instance(max_timers)
      logical init

      if (init) then
         do i = 1, max_timers
            descs(i) = descs_instance(i)
            if (descs(i)(1:1) .ne. ' ' .and. 
     *          descs(i)(1:1) .ne. char(0) ) then
               contrib(i) = 1.
               sumdata(i,1) = instance(i)
               sumdata(i,2) = instance(i)
               sumdata(i,3) = instance(i)
               sumsq(i) = instance(i)*instance(i)
            else
               contrib(i)   = 0.
               sumsq(i)     = 0.
               sumdata(i,1) = 0.
               sumdata(i,2) = 0.d0
               sumdata(i,3) = 1.d10 
            endif
         enddo 

         return
      endif

      do i = 1, max_timers
         if (descs_instance(i)(1:1) .ne. ' ' .and.
     *       descs_instance(i)(1:1) .ne. char(0)) then
            if (descs_instance(i) .eq. descs(i)) then
              
c------------------------------------------------------------------------
c   Sum in the data.
c------------------------------------------------------------------------
   
               if (instance(i) .ne. 0.d0) then
                  sumdata(i,1) = sumdata(i,1) + instance(i)
                  sumdata(i,2) = max(sumdata(i,2), instance(i))
                  sumdata(i,3) = min(sumdata(i,3), instance(i))
                  contrib(i)   = contrib(i) + 1.
                  sumsq(i)     = sumsq(i) + instance(i)*instance(i)
               endif   
            else
               print *,'Error: Timer desc ',descs_instance(i),
     *             ' does not match proc 0 timer_desc ',
     *              descs(i)
               print *,'i = ',i
               call abort_job()
            endif
         endif
      enddo
      return
      end