Testing And Benchmarking in Co-array Fortran

Here’s the translation of the Go testing and benchmarking example to Co-array Fortran:

! Testing and benchmarking in Co-array Fortran

! Unit testing is an important part of writing principled programs.
! While Fortran doesn't have a built-in testing framework like Go's testing package,
! we can create our own simple testing framework.

module intutils
    implicit none
    
    contains
    
    ! This is the function we'll be testing
    function int_min(a, b) result(res)
        integer, intent(in) :: a, b
        integer :: res
        
        if (a < b) then
            res = a
        else
            res = b
        end if
    end function int_min
    
end module intutils

program test_int_min
    use intutils
    implicit none
    
    ! Basic test
    call test_int_min_basic()
    
    ! Table-driven test
    call test_int_min_table_driven()
    
    contains
    
    subroutine test_int_min_basic()
        integer :: ans
        
        ans = int_min(2, -2)
        if (ans /= -2) then
            print *, "Error: int_min(2, -2) = ", ans, "; want -2"
        else
            print *, "PASS: int_min(2, -2)"
        end if
    end subroutine test_int_min_basic
    
    subroutine test_int_min_table_driven()
        integer :: i
        integer, dimension(5,3) :: tests = reshape([ &
            0,  1,  0, &
            1,  0,  0, &
            2, -2, -2, &
            0, -1, -1, &
           -1,  0, -1  &
        ], [5,3])
        
        do i = 1, size(tests, 1)
            call run_test(tests(i,1), tests(i,2), tests(i,3))
        end do
    end subroutine test_int_min_table_driven
    
    subroutine run_test(a, b, want)
        integer, intent(in) :: a, b, want
        integer :: ans
        
        ans = int_min(a, b)
        if (ans /= want) then
            print *, "Error: int_min(", a, ",", b, ") = ", ans, "; want ", want
        else
            print *, "PASS: int_min(", a, ",", b, ")"
        end if
    end subroutine run_test
    
end program test_int_min

In this Co-array Fortran version:

  1. We define our int_min function in a module called intutils.

  2. We create a test program that includes both a basic test and a table-driven test.

  3. The test_int_min_basic subroutine demonstrates a simple test case.

  4. The test_int_min_table_driven subroutine shows how to implement a table-driven test in Fortran. We use a 2D array to store our test cases.

  5. The run_test subroutine is a helper that runs individual test cases and reports results.

Note that Fortran doesn’t have a built-in testing framework like Go’s, so we’ve implemented a simple version that prints “PASS” for successful tests and “Error” messages for failed tests.

To run these tests, you would compile and run the program:

$ gfortran -o test_int_min test_int_min.f90
$ ./test_int_min

Benchmarking in Fortran typically involves using system-specific timing routines and running the function many times in a loop. Here’s a simple example of how you might benchmark the int_min function:

program benchmark_int_min
    use intutils
    implicit none
    
    integer :: i, start_time, end_time, count_rate
    integer, parameter :: n = 1000000
    
    call system_clock(start_time, count_rate)
    
    do i = 1, n
        call int_min(1, 2)
    end do
    
    call system_clock(end_time)
    
    print *, "Time taken for ", n, " calls: ", &
             real(end_time - start_time) / real(count_rate), " seconds"
             
end program benchmark_int_min

This benchmark program uses the system_clock subroutine to measure the time taken to call int_min a million times. You would compile and run it separately from the test program:

$ gfortran -o benchmark_int_min benchmark_int_min.f90
$ ./benchmark_int_min

Remember that the exact syntax and available features may vary depending on your specific Co-array Fortran implementation.