Print statistics
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
type(mp_comm_type), | intent(in) | :: | group | |||
integer, | intent(in) | :: | output_unit |
SUBROUTINE dbcsr_multiply_print_statistics(group, output_unit) !! Print statistics TYPE(mp_comm_type), INTENT(IN) :: group INTEGER, INTENT(IN) :: output_unit INTEGER(KIND=int_8) :: total_nexchanged INTEGER(KIND=int_8), & DIMENSION(SIZE(dbcsr_mpi_size_limits) + 1, 2, 2) :: total_recv_breakdown REAL :: average, total_marketing_flops, & total_max_memory REAL, DIMENSION(2) :: max_recv_data, min_recv_data, & total_recv_data INTEGER :: ilimit, isqrt, isqrt2 CHARACTER(len=1000) :: msg call dbcsr_mm_sched_print_statistics(group, output_unit) total_max_memory = max_memory CALL mp_max(total_max_memory, group) total_marketing_flops = marketing_flops CALL mp_sum(total_marketing_flops, group) total_nexchanged = dbcsr_mpi_statistics%nexchanged CALL mp_sum(total_nexchanged, group) total_recv_data(:) = dbcsr_mpi_statistics%data_size(:, 1) CALL mp_sum(total_recv_data, group) min_recv_data(:) = dbcsr_mpi_statistics%data_size(:, 2) CALL mp_min(min_recv_data, group) max_recv_data(:) = dbcsr_mpi_statistics%data_size(:, 3) CALL mp_max(max_recv_data, group) IF (dbcsr_mpi_statistics%nexchanged .GT. 0) THEN average = SUM(total_recv_data(:))/REAL(total_nexchanged) ELSE average = 0 min_recv_data = 0 END IF total_recv_breakdown(:, :, :) = dbcsr_mpi_statistics%data_size_breakdown(:, :, :) CALL mp_sum(total_recv_breakdown, group) IF (output_unit > 0) THEN WRITE (output_unit, '(A,T30,EN20.6)') " marketing flops", total_marketing_flops IF (dbcsr_mpi_statistics%nimages .GT. 0) THEN WRITE (UNIT=output_unit, FMT="(T2,A)") REPEAT("-", 79) WRITE (output_unit, '(A,T30,I20)') " # multiplications", num_multiplications WRITE (output_unit, '(A,T30,EN20.6)') " max memory usage/rank", total_max_memory WRITE (output_unit, '(A,T30,I20)') " # max total images/rank", dbcsr_mpi_statistics%nimages WRITE (output_unit, '(A,T30,I20)') " # max 3D layers", get_max_layers_3D() WRITE (output_unit, '(A,T30,I20)') " # MPI messages exchanged", total_nexchanged IF (total_nexchanged > 0) THEN ! omit noisy output in single-node case WRITE (output_unit, '(A)') " MPI messages size (bytes):" WRITE (output_unit, '(A,T30,EN20.6)') " total size", & SUM(total_recv_data(:)) WRITE (output_unit, '(A,T30,EN20.6)') " min size", & MINVAL(min_recv_data(:)) WRITE (output_unit, '(A,T30,EN20.6)') " max size", & MAXVAL(max_recv_data(:)) WRITE (output_unit, '(A,T30,EN20.6)') " average size", average WRITE (output_unit, '(A)') " MPI breakdown and total messages size (bytes):" WRITE (output_unit, '(A,I8,T40,I10,T55,I20)') " size <= ", dbcsr_mpi_size_limits(1), & SUM(total_recv_breakdown(1, 1, :)), SUM(total_recv_breakdown(1, 2, :)) DO ilimit = 2, SIZE(dbcsr_mpi_size_limits) WRITE (output_unit, '(A,I8,A,I8,T40,I10,T55,I20)') " ", dbcsr_mpi_size_limits(ilimit - 1), & " < size <= ", dbcsr_mpi_size_limits(ilimit), & SUM(total_recv_breakdown(ilimit, 1, :)), SUM(total_recv_breakdown(ilimit, 2, :)) END DO ilimit = SIZE(dbcsr_mpi_size_limits) WRITE (output_unit, '(A,I8,A,T40,I10,T55,I20)') " ", dbcsr_mpi_size_limits(ilimit), & " < size ", SUM(total_recv_breakdown(ilimit + 1, 1, :)), SUM(total_recv_breakdown(ilimit + 1, 2, :)) END IF END IF isqrt = NINT(SQRT(REAL(dbcsr_mpi_statistics%last_mpi_ranks_used, KIND=real_8))) isqrt2 = NINT(SQRT(REAL(dbcsr_mpi_statistics%last_mpi_ranks_used*2, KIND=real_8))) IF (isqrt*isqrt .NE. dbcsr_mpi_statistics%last_mpi_ranks_used) THEN WRITE (UNIT=output_unit, FMT="(T2,A)") REPEAT("-", 79) WRITE (UNIT=msg, FMT="(A,I0,A,2(I0,1X))") & "Using a non-square number of MPI ranks might lead to poor performance."// & " Used ranks: ", dbcsr_mpi_statistics%last_mpi_ranks_used, & " Suggested: ", isqrt**2, isqrt2**2 DBCSR_WARN(msg) END IF END IF END SUBROUTINE dbcsr_multiply_print_statistics