Times each available method for the given problem size and returns the flag of the fastest one.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
integer, | intent(in) | :: | trial_size | |||
integer, | intent(in), | optional | :: | repeats | ||
logical, | intent(in), | optional | :: | display_times |
function recommend_multiplication_method(trial_size, repeats, display_times) result(method)
use job_manage, only: timer_local
use file_utils, only: error_unit
use ran, only: ranf
use optionals, only: get_option_with_default
implicit none
integer, intent(in) :: trial_size
integer, intent(in), optional :: repeats
logical, intent(in), optional :: display_times
type(matrix_multiply_method_type) :: method
real :: start_time
integer :: method_index, j, k
complex, dimension(:, :), allocatable :: a, b, c
integer :: error, number_of_methods, number_of_repeats, repeat
real, dimension(:), allocatable :: times
logical :: should_display_times
! Initialise to invalid method flag
method = matrix_multiply_method_type(flag = -1)
! Try to allocate matrix of trial_size, if it doesn't work report error
! and return.
allocate(a(trial_size, trial_size), stat = error)
allocate(b(trial_size, trial_size), stat = error)
allocate(c(trial_size, trial_size), stat = error)
if (error > 0) then
write(error_unit(), '("Unable to allocated trial array with size ",I0)') trial_size
return
end if
! Initialise arrays
do j = 1, trial_size
do k = 1, trial_size
a(j,k) = cmplx(ranf(), ranf())
b(j,k) = a(j,k)
c(j,k) = 0.0
end do
end do
number_of_methods = size(multiply_methods)
allocate(times(number_of_methods))
times = 0.0
number_of_repeats = get_option_with_default(repeats, 1)
should_display_times = get_option_with_default(display_times, .false.)
! Time each method
do method_index = 1, number_of_methods
start_time = timer_local()
do repeat = 1, number_of_repeats
c = matmul_wrapper(a, b, multiply_methods(method_index))
end do
times(method_index) = timer_local() - start_time
end do
! Report the results if requested
if (should_display_times) then
write(*,'("Matrix multiplication benchmark : ",I0,&
&" repeats of square matrices with size ",I0)') number_of_repeats, trial_size
write(*,'("Method",T18,"Total time (s)")')
do method_index = 1, number_of_methods
method = multiply_methods(method_index)
write(*,'(A16,T18,F12.8)') trim(method%get_name()), times(method_index)
end do
end if
! Recommend the method with the smallest time
method = multiply_methods( minloc(times, dim = 1))
end function recommend_multiplication_method