Guest User

some fortran benchmark

a guest
Nov 17th, 2020
166
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. program main
  2.   implicit none
  3.   integer N
  4.  
  5.   N = 100
  6.   DO
  7.     call runtest(nint(1.0*N))
  8.     call runtest(nint(1.5*N))
  9.     call runtest(nint(2.0*N))
  10.     call runtest(nint(3.5*N))
  11.     call runtest(nint(5.0*N))
  12.     call runtest(nint(7.0*N))
  13.     N = N * 10
  14.   END DO
  15.  
  16.  
  17.   call runtest(300)
  18.  
  19. contains
  20.  
  21.   subroutine do_matmul(N,A,B,C)
  22.     integer, intent(in) :: N
  23.     integer, intent(in) :: A(:,:), B(:,:)
  24.     integer, intent(out) :: C(:,:)
  25.     C = matmul(A,B)
  26.   end subroutine do_matmul
  27.  
  28.   subroutine do_sum(N,A,B,C)
  29.     integer, intent(in) :: N
  30.     integer, intent(in) :: A(:,:), B(:,:)
  31.     integer, intent(out) :: C(:,:)
  32.     integer i,j,k
  33.     DO i = 1, N
  34.       DO j = 1, N
  35.         C(i,j) = sum( [(A(i,k)*B(k,j), k = 1, N)] )
  36.       END DO
  37.     END DO
  38.   end subroutine do_sum
  39.  
  40.   subroutine do_nointrinsic1(N,A,B,C)
  41.     integer, intent(in) :: N
  42.     integer, intent(in) :: A(:,:), B(:,:)
  43.     integer, intent(out) :: C(:,:)
  44.     integer i,j,k, tmp
  45.     DO i = 1, N
  46.       DO j = 1, N
  47.         tmp = 0
  48.         DO k = 1, N
  49.           tmp = tmp + A(i,k) * B(k,j)
  50.         END DO
  51.         C(i,j) = tmp
  52.       END DO
  53.     END DO
  54.   end subroutine do_nointrinsic1
  55.  
  56.   subroutine do_nointrinsic2(N,A,B,C)
  57.     integer, intent(in) :: N
  58.     integer, intent(in) :: A(:,:), B(:,:)
  59.     integer, intent(out) :: C(:,:)
  60.     integer i,j,k
  61.     DO i = 1, N
  62.       DO j = 1, N
  63.         C(i,j) = 0
  64.         DO k = 1, N
  65.           C(i,j) = C(i,j) + A(i,k) * B(k,j)
  66.         END DO
  67.       END DO
  68.     END DO
  69.   end subroutine do_nointrinsic2
  70.  
  71.   real function runtest1(N, name, subrout, o_reftime, o_refname) result(time)
  72.     integer, intent(in) :: N
  73.     character(*), target, intent(in) :: name
  74.     interface
  75.        subroutine subrout(N,A,B,C)
  76.          integer, intent(in) :: N
  77.          integer, intent(in) :: A(:,:), B(:,:)
  78.          integer, intent(out) :: C(:,:)
  79.        end subroutine subrout
  80.     end interface
  81.     real, intent(in), optional :: o_reftime
  82.     character(*), target, intent(in), optional :: o_refname
  83.  
  84.     ! locals
  85.     integer A(N,N), B(N,N), C(N,N)    ! It's just a benchmark, so we don't need to initialize the matrices.
  86.     real start, end, reftime
  87.     character(:), pointer :: refname
  88.  
  89.     ! body
  90.     call CPU_TIME(start)
  91.     call subrout(N,A,B,C)
  92.     call CPU_TIME(end)
  93.     time = end-start
  94.  
  95.     if(present(o_reftime)) then
  96.        reftime = o_reftime
  97.     else
  98.        reftime = time
  99.     end if
  100.  
  101.     if(present(o_refname)) then
  102.        refname => o_refname
  103.     else
  104.        refname => name
  105.     end if
  106.  
  107.     print '(3x, A,F20.6," seconds, ",F10.3," x time of ",A)', name, time, time/reftime, trim(refname)
  108.   end function runtest1
  109.  
  110.   subroutine runtest(N)
  111.     integer, intent(in) :: N
  112.     real :: time_n1, time_n2, time_sm, time_mm
  113.     print '("N = ", I0)', N
  114.     time_mm = runtest1(N, "matmul      ", do_matmul)
  115.     time_sm = runtest1(N, "sum         ", do_sum,          time_mm, "matmul")
  116.     time_n1 = runtest1(N, "nointrinsic1", do_nointrinsic1, time_mm, "matmul")
  117.     time_n2 = runtest1(N, "nointrinsic2", do_nointrinsic2, time_mm, "matmul")
  118.   end subroutine runtest
  119.  
  120. end program main
  121.  
Advertisement
Add Comment
Please, Sign In to add comment