dbcsr_multiply_print_statistics Subroutine

public subroutine dbcsr_multiply_print_statistics(group, output_unit)

Print statistics

Arguments

Type IntentOptional Attributes Name
type(mp_comm_type), intent(in) :: group
integer, intent(in) :: output_unit

Source Code

   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