!----------------------------------------------------------------------
!     Copyright (c) 2025 Shin-ichi Takehiro. All rights reserved.
!----------------------------------------------------------------------
!
!表題  ua_mpi_module 速度計測プログラム
!
!履歴  2025/10/04  竹広真一
!
program ua_mpi_module_bench

  use dc_message, only : MessageNotify
  use dc_test, only : AssertEqual
#ifdef SPML1
  use wa_mpi_module, ua_pva=>wa_xva, pva_ua=>xva_wa
#else
  use ua_mpi_module
#endif
  use mpi
  !$ use omp_lib
  implicit none

!  integer, parameter :: im=4096, jm=2048, nm=2047, km=20
!  integer, parameter :: im=2048, jm=1024, nm=1023, km=20
!  integer, parameter :: im=2048, jm=1024, nm=683, km=20
!  integer, parameter :: im=1024, jm=512, nm=341, km=20
!  integer, parameter :: im=512, jm=256, nm=85, km=20
  integer, parameter :: im=512, jm=256, nm=85, km=20
!  integer, parameter :: im=256, jm=128, nm=85, km=20
!  integer, parameter :: im=128, jm=64, nm=42, km=20
!  integer, parameter :: im=64, jm=32, nm=21, km=20
!  integer, parameter :: im=32, jm=16, nm=10, km=3
  integer, parameter :: npv=1

  real(8), allocatable ::  ua_data(:,:)
  real(8), allocatable ::  pva_data(:,:,:)


  ! 判定誤差設定
  integer, parameter :: check_digits = 10
  integer, parameter :: ignore = -11

  integer :: ntr=10
  real(8) :: ran,gflops,rc,tim0,tim1  
  integer :: ierr
  integer :: ip, np
  integer :: it, k, n
  integer :: maxtd
  integer :: nwmax
  integer :: nlon

  !---------------- MPI スタート ---------------------
  CALL MPI_INIT(IERR)
  CALL MPI_COMM_RANK(MPI_COMM_WORLD,IP,IERR)
  CALL MPI_COMM_SIZE(MPI_COMM_WORLD,NP,IERR)

#ifdef SPML1  
  call wa_mpi_Initial( nm, im, jm, km )
#else
  if ( NP .lt. NPV ) &
       call MessageNotify('E','main','NP should be large equal to NPV.')
  call ua_mpi_Initial( nm, im, jm, km, npv=npv )
#endif

  !$       MAXTD=omp_get_max_threads()
  PRINT '(A,I3)','number of threads =',MAXTD
  PRINT '(A,I3)','number of processes =',NP

#ifdef SPML1
  nwmax = (nm+1)*(nm+1)
  nlon  = im
  allocate(ua_data(nwmax,km))
  allocate(pva_data(0:im-1,jc,km))
#else
  nwmax = nmc
  nlon  = ic
  allocate(ua_data(nmc,km))
  allocate(pva_data(0:ic-1,jc,km))
#endif
  
  RC=(1D0*5*IM*LOG(1D0*IM)/LOG(2D0)*0.5D0*JM+1D0*(NM+1)*(NM+1)*JM )*km

  !---- データ設定
  do k=1,km
     do n=1,nwmax
        call random_number(RAN)
        ua_data(n,k) = ran
     end do
  end do

 
  !---- 逆変換
  CALL MXTIME(TIM0)
  
  do it = 1, ntr
     pva_data = pva_ua(ua_data)
  end do
  
  CALL MXTIME(TIM1)
  GFLOPS=RC*NTR/(TIM1-TIM0)/1D9
  IF(IP.EQ.0) THEN
#ifdef SPML1
     PRINT '(A,ES9.2,A,F6.1,A)','xva_wa: ',(TIM1-TIM0)/NTR,' sec  (',  &
          &      GFLOPS,' GFlops)'
#else     
     PRINT '(A,ES9.2,A,F6.1,A)','pva_ua: ',(TIM1-TIM0)/NTR,' sec  (',  &
          &      GFLOPS,' GFlops)'
#endif
  END IF

  !---- 正変換
  CALL MXTIME(TIM0)
  
  do it = 1, ntr
     ua_data = ua_pva(pva_data)
  end do
  
  CALL MXTIME(TIM1)
  GFLOPS=RC*NTR/(TIM1-TIM0)/1D9
  IF(IP.EQ.0) THEN
#ifdef SPML1
     PRINT '(A,ES9.2,A,F6.1,A)','wa_xva: ',(TIM1-TIM0)/NTR,' sec  (',  &
          &      GFLOPS,' GFlops)'
#else
     PRINT '(A,ES9.2,A,F6.1,A)','ua_pva: ',(TIM1-TIM0)/NTR,' sec  (',  &
          &      GFLOPS,' GFlops)'
#endif
  END IF

 !------ MPIの終了 ------

  call MPI_FINALIZE(IERR)

end program ua_mpi_module_bench

