|
| 1 | +module prif_run_tests |
| 2 | + use iso_c_binding, only: c_int64_t, c_size_t, c_ptr, c_null_ptr, c_null_funptr, c_f_pointer |
| 3 | + use iso_fortran_env, only: int64, output_unit, error_unit |
| 4 | + use iso_varying_string, only: put_line, var_str, operator(//) |
| 5 | + use prif, only: & |
| 6 | + prif_this_image_no_coarray, prif_num_images, & |
| 7 | + prif_critical_type, prif_coarray_handle, & |
| 8 | + prif_allocate_coarray, prif_deallocate_coarray, & |
| 9 | + prif_co_reduce, prif_operation_wrapper_interface |
| 10 | + use strff, only: to_string |
| 11 | + use veggies, only: filter_item_result_t, test_item_t, test_result_item_t |
| 12 | + use veggies_command_line_m, only: options_t, get_options, DEBUG |
| 13 | + |
| 14 | + implicit none |
| 15 | + private |
| 16 | + public :: run_tests |
| 17 | +contains |
| 18 | + function run_tests(tests) result(passed) |
| 19 | + type(test_item_t), intent(in) :: tests |
| 20 | + logical :: passed |
| 21 | + |
| 22 | + integer(int64) :: clock_rate |
| 23 | + real :: elapsed_time |
| 24 | + integer(int64) :: end_time |
| 25 | + type(filter_item_result_t) :: filtered_tests |
| 26 | + type(options_t) :: options |
| 27 | + type(test_result_item_t) :: results |
| 28 | + integer(int64) :: start_time |
| 29 | + logical :: suite_failed |
| 30 | + type(test_item_t) :: tests_to_run |
| 31 | + integer :: i, me, ni |
| 32 | + |
| 33 | + suite_failed = .false. |
| 34 | + |
| 35 | + options = get_options() |
| 36 | + |
| 37 | + tests_to_run = tests |
| 38 | + do i = 1, size(options%filter_strings) |
| 39 | + filtered_tests = tests_to_run%filter(options%filter_strings(i)) |
| 40 | + if (filtered_tests%matched()) then |
| 41 | + tests_to_run = filtered_tests%test() |
| 42 | + else |
| 43 | + call put_line(error_unit, "No matching tests found") |
| 44 | + passed = .false. |
| 45 | + return |
| 46 | + end if |
| 47 | + end do |
| 48 | + |
| 49 | + call prif_this_image_no_coarray(this_image=me) |
| 50 | + call prif_num_images(ni) |
| 51 | + if (me == 1) then |
| 52 | + call put_line(output_unit, "Running Tests") |
| 53 | + call put_line(output_unit, "") |
| 54 | + |
| 55 | + if (.not.options%quiet) then |
| 56 | + call put_line(output_unit, tests_to_run%description()) |
| 57 | + call put_line(output_unit, "") |
| 58 | + end if |
| 59 | + |
| 60 | + call put_line( & |
| 61 | + output_unit, & |
| 62 | + "A total of " // to_string(tests_to_run%num_cases()) // " test cases") |
| 63 | + call put_line(output_unit, "") |
| 64 | + end if |
| 65 | + |
| 66 | + if (DEBUG) call put_line( & |
| 67 | + "Beginning execution of test suite" & |
| 68 | + // merge(" on image " // to_string(me), var_str(""), ni > 1)) |
| 69 | + call system_clock(start_time, clock_rate) |
| 70 | + results = tests_to_run%run() |
| 71 | + call system_clock(end_time) |
| 72 | + if (DEBUG) call put_line( & |
| 73 | + "Completed execution of test suite." & |
| 74 | + // merge(" on image " // to_string(me), var_str(""), ni > 1)) |
| 75 | + elapsed_time = real(end_time - start_time) / real(clock_rate) |
| 76 | + |
| 77 | + block |
| 78 | + type(prif_critical_type) :: critical_mold |
| 79 | + type(prif_coarray_handle) :: critical_coarray |
| 80 | + type(c_ptr) :: allocated_memory |
| 81 | + |
| 82 | + call prif_allocate_coarray( & |
| 83 | + lcobounds = [1_c_int64_t], & |
| 84 | + ucobounds = [int(ni, kind=c_int64_t)], & |
| 85 | + size_in_bytes = storage_size(critical_mold, kind=c_size_t), & |
| 86 | + final_func = c_null_funptr, & |
| 87 | + coarray_handle = critical_coarray, & |
| 88 | + allocated_memory = allocated_memory) |
| 89 | + call prif_critical(critical_coarray) |
| 90 | + if (ni > 1) then |
| 91 | + call put_line(output_unit, "On image " // to_string(me)) |
| 92 | + end if |
| 93 | + if (results%passed()) then |
| 94 | + call put_line(output_unit, "All Passed") |
| 95 | + call put_line( & |
| 96 | + output_unit, & |
| 97 | + "Took " // to_string(elapsed_time, 6) // " seconds") |
| 98 | + call put_line(output_unit, "") |
| 99 | + if (options%verbose) then |
| 100 | + call put_line( & |
| 101 | + output_unit, & |
| 102 | + results%verbose_description(options%colorize)) |
| 103 | + call put_line(output_unit, "") |
| 104 | + end if |
| 105 | + call put_line( & |
| 106 | + output_unit, & |
| 107 | + "A total of " // to_string(results%num_cases()) & |
| 108 | + // " test cases containing a total of " & |
| 109 | + // to_string(results%num_asserts()) // " assertions") |
| 110 | + call put_line(output_unit, "") |
| 111 | + else |
| 112 | + call put_line(error_unit, "Failed") |
| 113 | + call put_line( & |
| 114 | + error_unit, & |
| 115 | + "Took " // to_string(elapsed_time, 6) // " seconds") |
| 116 | + call put_line(error_unit, "") |
| 117 | + if (options%verbose) then |
| 118 | + call put_line( & |
| 119 | + error_unit, & |
| 120 | + results%verbose_description(options%colorize)) |
| 121 | + else |
| 122 | + call put_line( & |
| 123 | + error_unit, & |
| 124 | + results%failure_description(options%colorize)) |
| 125 | + end if |
| 126 | + call put_line(error_unit, "") |
| 127 | + call put_line( & |
| 128 | + error_unit, & |
| 129 | + to_string(results%num_failing_cases()) // " of " & |
| 130 | + // to_string(results%num_cases()) // " cases failed") |
| 131 | + call put_line( & |
| 132 | + error_unit, & |
| 133 | + to_string(results%num_failing_asserts()) // " of " & |
| 134 | + // to_string(results%num_asserts()) // " assertions failed") |
| 135 | + call put_line(error_unit, "") |
| 136 | + suite_failed = .true. |
| 137 | + end if |
| 138 | + |
| 139 | + call prif_end_critical(critical_coarray) |
| 140 | + call prif_deallocate_coarray([critical_coarray]) |
| 141 | + end block |
| 142 | + if (any_image_failed(suite_failed)) then |
| 143 | + passed = .false. |
| 144 | + else |
| 145 | + passed = .true. |
| 146 | + end if |
| 147 | + end function |
| 148 | + |
| 149 | + function any_image_failed(image_failed) |
| 150 | + logical, intent(in) :: image_failed |
| 151 | + logical :: any_image_failed |
| 152 | + |
| 153 | + any_image_failed = image_failed |
| 154 | + call co_any(any_image_failed) |
| 155 | + end function |
| 156 | + |
| 157 | + subroutine co_any(x) |
| 158 | + logical, intent(inout) :: x |
| 159 | + |
| 160 | + procedure(prif_operation_wrapper_interface), pointer :: op |
| 161 | + |
| 162 | + op => or_wrapper |
| 163 | + call prif_co_reduce(x, op, c_null_ptr) |
| 164 | + end subroutine |
| 165 | + |
| 166 | + subroutine or_wrapper(arg1, arg2_and_out, count, cdata) bind(C) |
| 167 | + type(c_ptr), intent(in), value :: arg1, arg2_and_out |
| 168 | + integer(c_size_t), intent(in), value :: count |
| 169 | + type(c_ptr), intent(in), value :: cdata |
| 170 | + |
| 171 | + logical, pointer :: lhs(:), rhs_and_result(:) |
| 172 | + integer(c_size_t) :: i |
| 173 | + |
| 174 | + if (count == 0) return |
| 175 | + call c_f_pointer(arg1, lhs, [count]) |
| 176 | + call c_f_pointer(arg2_and_out, rhs_and_result, [count]) |
| 177 | + do i = 1, count |
| 178 | + rhs_and_result(i) = lhs(i).or.rhs_and_result(i) |
| 179 | + end do |
| 180 | + end subroutine |
| 181 | +end module |
0 commit comments