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

Last change on this file since 197 was 197, checked in by raasch, 13 years ago

further adjustments for SGI and other small changes

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