recommend_multiplication_method Function

public function recommend_multiplication_method(trial_size, repeats, display_times) result(method)

Times each available method for the given problem size and returns the flag of the fastest one.

Arguments

Type IntentOptional Attributes Name
integer, intent(in) :: trial_size
integer, intent(in), optional :: repeats
logical, intent(in), optional :: display_times

Return Value type(matrix_multiply_method_type)


Contents


Source Code

  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