source: palm/trunk/SOURCE/cpu_statistics.f90 @ 198

Last change on this file since 198 was 198, checked in by raasch, 16 years ago

file headers updated for the next release 3.5

  • Property svn:keywords set to Id
File size: 8.4 KB
Line 
1 SUBROUTINE cpu_statistics
2
3!------------------------------------------------------------------------------!
4! Actual revisions:
5! -----------------
6!
7!
8! Former revisions:
9! -----------------
10! $Id: cpu_statistics.f90 198 2008-09-17 08:55:28Z raasch $
11!
12! 197 2008-09-16 15:29:03Z raasch
13! Format adjustments in order to allow CPU# > 999,
14! data are collected from PE0 in an ordered sequence which seems to avoid
15! hanging of processes on SGI-ICE
16!
17! 82 2007-04-16 15:40:52Z raasch
18! Preprocessor directives for old systems removed
19!
20! RCS Log replace by Id keyword, revision history cleaned up
21!
22! Revision 1.13  2006/04/26 12:10:51  raasch
23! Output of number of threads per task, max = min in case of 1 PE
24!
25! Revision 1.1  1997/07/24 11:11:11  raasch
26! Initial revision
27!
28!
29! Description:
30! ------------
31! Analysis and output of the cpu-times measured. All PE results are collected
32! on PE0 in order to calculate the mean cpu-time over all PEs and other
33! statistics. The output is sorted according to the amount of cpu-time consumed
34! and output on PE0.
35!------------------------------------------------------------------------------!
36
37    USE cpulog
38    USE pegrid
39    USE control_parameters
40
41    IMPLICIT NONE
42
43    INTEGER    ::  i, ii(1), iii, lp, sender
44    REAL, SAVE ::  norm = 1.0
45    REAL, DIMENSION(:),   ALLOCATABLE ::  pe_max, pe_min, pe_rms, sum
46    REAL, DIMENSION(:,:), ALLOCATABLE ::  pe_log_points
47
48
49!
50!-- Compute cpu-times in seconds
51    log_point%mtime  = log_point%mtime  / norm
52    log_point%sum    = log_point%sum    / norm
53    log_point%vector = log_point%vector / norm
54    WHERE ( log_point%counts /= 0 )
55       log_point%mean = log_point%sum / log_point%counts
56    END WHERE
57
58
59!
60!-- Collect cpu-times from all PEs and calculate statistics
61    IF ( myid == 0 )  THEN
62!
63!--    Allocate and initialize temporary arrays needed for statistics
64       ALLOCATE( pe_max( SIZE( log_point ) ), pe_min( SIZE( log_point ) ), &
65                 pe_rms( SIZE( log_point ) ),                              &
66                 pe_log_points( SIZE( log_point ), 0:numprocs-1 ) )
67       pe_min = log_point%sum
68       pe_max = log_point%sum    ! need to be set in case of 1 PE
69       pe_rms = 0.0
70
71#if defined( __parallel )
72!
73!--    Receive data from all PEs
74       DO  i = 1, numprocs-1
75          CALL MPI_RECV( pe_max(1), SIZE( log_point ), MPI_REAL, &
76                         i, i, comm2d, status, ierr )
77          sender = status(MPI_SOURCE)
78          pe_log_points(:,sender) = pe_max
79       ENDDO
80       pe_log_points(:,0) = log_point%sum   ! Results from PE0
81!
82!--    Calculate mean of all PEs, store it on log_point%sum
83!--    and find minimum and maximum
84       DO  iii = 1, SIZE( log_point )
85          DO  i = 1, numprocs-1
86             log_point(iii)%sum = log_point(iii)%sum + pe_log_points(iii,i)
87             pe_min(iii) = MIN( pe_min(iii), pe_log_points(iii,i) )
88             pe_max(iii) = MAX( pe_max(iii), pe_log_points(iii,i) )
89          ENDDO
90          log_point(iii)%sum = log_point(iii)%sum / numprocs
91!
92!--       Calculate rms
93          DO  i = 0, numprocs-1
94             pe_rms(iii) = pe_rms(iii) + ( &
95                                 pe_log_points(iii,i) - log_point(iii)%sum &
96                                         )**2
97          ENDDO
98          pe_rms(iii) = SQRT( pe_rms(iii) / numprocs )
99       ENDDO
100    ELSE
101!
102!--    Send data to PE0 (pe_max is used as temporary storage to send
103!--    the data in order to avoid sending the data type log)
104       ALLOCATE( pe_max( SIZE( log_point ) ) )
105       pe_max = log_point%sum
106       CALL MPI_SEND( pe_max(1), SIZE( log_point ), MPI_REAL, 0, myid, comm2d, &
107                      ierr )
108#endif
109
110    ENDIF
111
112!
113!-- Write cpu-times
114    IF ( myid == 0 )  THEN
115!
116!--    Re-store sums
117       ALLOCATE( sum( SIZE( log_point ) ) )
118       WHERE ( log_point%counts /= 0 )
119          sum = log_point%sum
120       ELSEWHERE
121          sum = -1.0
122       ENDWHERE
123
124!
125!--    Write cpu-times sorted by size
126       CALL check_open( 18 )
127       WRITE ( 18, 100 )  TRIM( run_description_header ),        &
128                          numprocs * threads_per_task, pdims(1), pdims(2), &
129                          threads_per_task
130       DO
131          ii = MAXLOC( sum )
132          i = ii(1)
133          IF ( sum(i) /= -1.0 )  THEN
134             WRITE ( 18, 102 ) &
135                log_point(i)%place, log_point(i)%sum,                &
136                log_point(i)%sum / log_point(1)%sum * 100.0,         &
137                log_point(i)%counts, pe_min(i), pe_max(i), pe_rms(i)
138             sum(i) = -1.0
139          ELSE
140             EXIT
141          ENDIF
142       ENDDO
143    ENDIF
144
145
146!
147!-- The same procedure again for the individual measurements.
148!
149!-- Compute cpu-times in seconds
150    log_point_s%mtime  = log_point_s%mtime  / norm
151    log_point_s%sum    = log_point_s%sum    / norm
152    log_point_s%vector = log_point_s%vector / norm
153    WHERE ( log_point_s%counts /= 0 )
154       log_point_s%mean = log_point_s%sum / log_point_s%counts
155    END WHERE
156
157!
158!-- Collect cpu-times from all PEs and calculate statistics
159#if defined( __parallel )
160!
161!-- Set barrier in order to avoid that PE0 receives log_point_s-data
162!-- while still busy with receiving log_point-data (see above)
163    CALL MPI_BARRIER( comm2d, ierr )   
164#endif
165    IF ( myid == 0 )  THEN
166!
167!--    Initialize temporary arrays needed for statistics
168       pe_min = log_point_s%sum
169       pe_max = log_point_s%sum    ! need to be set in case of 1 PE
170       pe_rms = 0.0
171
172#if defined( __parallel )
173!
174!--    Receive data from all PEs
175       DO  i = 1, numprocs-1
176          CALL MPI_RECV( pe_max(1), SIZE( log_point ), MPI_REAL, &
177                         MPI_ANY_SOURCE, MPI_ANY_TAG, comm2d, status, ierr )
178          sender = status(MPI_SOURCE)
179          pe_log_points(:,sender) = pe_max
180       ENDDO
181       pe_log_points(:,0) = log_point_s%sum   ! Results from PE0
182!
183!--    Calculate mean of all PEs, store it on log_point_s%sum
184!--    and find minimum and maximum
185       DO  iii = 1, SIZE( log_point )
186          DO  i = 1, numprocs-1
187             log_point_s(iii)%sum = log_point_s(iii)%sum + pe_log_points(iii,i)
188             pe_min(iii) = MIN( pe_min(iii), pe_log_points(iii,i) )
189             pe_max(iii) = MAX( pe_max(iii), pe_log_points(iii,i) )
190          ENDDO
191          log_point_s(iii)%sum = log_point_s(iii)%sum / numprocs
192!
193!--       Calculate rms
194          DO  i = 0, numprocs-1
195             pe_rms(iii) = pe_rms(iii) + ( &
196                                 pe_log_points(iii,i) - log_point_s(iii)%sum &
197                                         )**2
198          ENDDO
199          pe_rms(iii) = SQRT( pe_rms(iii) / numprocs )
200       ENDDO
201    ELSE
202!
203!--    Send data to PE0 (pe_max is used as temporary storage to send
204!--    the data in order to avoid sending the data type log)
205       pe_max = log_point_s%sum
206       CALL MPI_SEND( pe_max(1), SIZE( log_point ), MPI_REAL, 0, 0, comm2d, &
207                      ierr )
208#endif
209
210    ENDIF
211
212!
213!-- Write cpu-times
214    IF ( myid == 0 )  THEN
215!
216!--    Re-store sums
217       WHERE ( log_point_s%counts /= 0 )
218          sum = log_point_s%sum
219       ELSEWHERE
220          sum = -1.0
221       ENDWHERE
222
223!
224!--    Write cpu-times sorted by size
225       WRITE ( 18, 101 )
226       DO
227          ii = MAXLOC( sum )
228          i = ii(1)
229          IF ( sum(i) /= -1.0 )  THEN
230             WRITE ( 18, 102 ) &
231                log_point_s(i)%place, log_point_s(i)%sum, &
232                log_point_s(i)%sum / log_point(1)%sum * 100.0, &
233                log_point_s(i)%counts, pe_min(i), pe_max(i), pe_rms(i)
234             sum(i) = -1.0
235          ELSE
236             EXIT
237          ENDIF
238       ENDDO
239
240!
241!--    Empty lines in order to create a gap to the results of the model
242!--    continuation runs
243       WRITE ( 18, 103 )
244
245!
246!--    Unit 18 is not needed anymore
247       CALL close_file( 18 )
248
249    ENDIF
250
251
252100 FORMAT (A/11('-')//'CPU measures for ',I5,' PEs (',I5,'(x) * ',I5,'(y', &
253            &') tasks *',I5,' threads):'/ &
254             &'----------------------------------------------------------', &
255             &'------------'//&
256            &'place:                        mean        counts      min  ', &
257             &'     max       rms'/ &
258            &'                           sec.      %                sec. ', &
259             &'     sec.      sec.'/  &
260            &'-----------------------------------------------------------', &
261             &'-------------------')
262
263101 FORMAT (/'special measures:'/ &
264            &'-----------------------------------------------------------', &
265            &'--------------------')
266
267102 FORMAT (A20,2X,F9.3,2X,F7.2,1X,I7,3(1X,F9.3))
268103 FORMAT (//)
269
270 END SUBROUTINE cpu_statistics
271
Note: See TracBrowser for help on using the repository browser.