|
| 1 | +module m_omp_backend |
| 2 | + use m_allocator, only: allocator_t, field_t |
| 3 | + use m_base_backend, only: base_backend_t |
| 4 | + use m_common, only: dp, globs_t |
| 5 | + use m_tdsops, only: dirps_t, tdsops_t |
| 6 | + |
| 7 | + use m_omp_common, only: SZ |
| 8 | + |
| 9 | + implicit none |
| 10 | + |
| 11 | + type, extends(base_backend_t) :: omp_backend_t |
| 12 | + !character(len=*), parameter :: name = 'omp' |
| 13 | + integer :: MPI_FP_PREC = dp |
| 14 | + real(dp), allocatable, dimension(:, :, :) :: & |
| 15 | + u_recv_s, u_recv_e, u_send_s, u_send_e, & |
| 16 | + v_recv_s, v_recv_e, v_send_s, v_send_e, & |
| 17 | + w_recv_s, w_recv_e, w_send_s, w_send_e, & |
| 18 | + du_send_s, du_send_e, du_recv_s, du_recv_e, & |
| 19 | + dud_send_s, dud_send_e, dud_recv_s, dud_recv_e, & |
| 20 | + d2u_send_s, d2u_send_e, d2u_recv_s, d2u_recv_e |
| 21 | + contains |
| 22 | + procedure :: alloc_tdsops => alloc_omp_tdsops |
| 23 | + procedure :: transeq_x => transeq_x_omp |
| 24 | + procedure :: transeq_y => transeq_y_omp |
| 25 | + procedure :: transeq_z => transeq_z_omp |
| 26 | + procedure :: trans_x2y => trans_x2y_omp |
| 27 | + procedure :: trans_x2z => trans_x2z_omp |
| 28 | + procedure :: sum_yzintox => sum_yzintox_omp |
| 29 | + procedure :: set_fields => set_fields_omp |
| 30 | + procedure :: get_fields => get_fields_omp |
| 31 | + end type omp_backend_t |
| 32 | + |
| 33 | + interface omp_backend_t |
| 34 | + module procedure init |
| 35 | + end interface omp_backend_t |
| 36 | + |
| 37 | + contains |
| 38 | + |
| 39 | + function init(globs, allocator) result(backend) |
| 40 | + implicit none |
| 41 | + |
| 42 | + class(globs_t) :: globs |
| 43 | + class(allocator_t), target, intent(inout) :: allocator |
| 44 | + type(omp_backend_t) :: backend |
| 45 | + |
| 46 | + integer :: n_halo, n_block |
| 47 | + |
| 48 | + select type(allocator) |
| 49 | + type is (allocator_t) |
| 50 | + ! class level access to the allocator |
| 51 | + backend%allocator => allocator |
| 52 | + end select |
| 53 | + |
| 54 | + n_halo = 4 |
| 55 | + n_block = globs%n_groups_x |
| 56 | + |
| 57 | + allocate(backend%u_send_s(SZ, n_halo, n_block)) |
| 58 | + allocate(backend%u_send_e(SZ, n_halo, n_block)) |
| 59 | + allocate(backend%u_recv_s(SZ, n_halo, n_block)) |
| 60 | + allocate(backend%u_recv_e(SZ, n_halo, n_block)) |
| 61 | + allocate(backend%v_send_s(SZ, n_halo, n_block)) |
| 62 | + allocate(backend%v_send_e(SZ, n_halo, n_block)) |
| 63 | + allocate(backend%v_recv_s(SZ, n_halo, n_block)) |
| 64 | + allocate(backend%v_recv_e(SZ, n_halo, n_block)) |
| 65 | + allocate(backend%w_send_s(SZ, n_halo, n_block)) |
| 66 | + allocate(backend%w_send_e(SZ, n_halo, n_block)) |
| 67 | + allocate(backend%w_recv_s(SZ, n_halo, n_block)) |
| 68 | + allocate(backend%w_recv_e(SZ, n_halo, n_block)) |
| 69 | + |
| 70 | + allocate(backend%du_send_s(SZ, 1, n_block)) |
| 71 | + allocate(backend%du_send_e(SZ, 1, n_block)) |
| 72 | + allocate(backend%du_recv_s(SZ, 1, n_block)) |
| 73 | + allocate(backend%du_recv_e(SZ, 1, n_block)) |
| 74 | + allocate(backend%dud_send_s(SZ, 1, n_block)) |
| 75 | + allocate(backend%dud_send_e(SZ, 1, n_block)) |
| 76 | + allocate(backend%dud_recv_s(SZ, 1, n_block)) |
| 77 | + allocate(backend%dud_recv_e(SZ, 1, n_block)) |
| 78 | + allocate(backend%d2u_send_s(SZ, 1, n_block)) |
| 79 | + allocate(backend%d2u_send_e(SZ, 1, n_block)) |
| 80 | + allocate(backend%d2u_recv_s(SZ, 1, n_block)) |
| 81 | + allocate(backend%d2u_recv_e(SZ, 1, n_block)) |
| 82 | + |
| 83 | + end function init |
| 84 | + |
| 85 | + subroutine alloc_omp_tdsops(self, tdsops, n, dx, operation, scheme) |
| 86 | + implicit none |
| 87 | + |
| 88 | + class(omp_backend_t) :: self |
| 89 | + class(tdsops_t), allocatable, intent(inout) :: tdsops |
| 90 | + integer, intent(in) :: n |
| 91 | + real(dp), intent(in) :: dx |
| 92 | + character(*), intent(in) :: operation, scheme |
| 93 | + |
| 94 | + allocate(tdsops_t :: tdsops) |
| 95 | + |
| 96 | + select type (tdsops) |
| 97 | + type is (tdsops_t) |
| 98 | + tdsops = tdsops_t(n, dx, operation, scheme) |
| 99 | + end select |
| 100 | + |
| 101 | + end subroutine alloc_omp_tdsops |
| 102 | + |
| 103 | + subroutine transeq_x_omp(self, du, dv, dw, u, v, w, dirps) |
| 104 | + implicit none |
| 105 | + |
| 106 | + class(omp_backend_t) :: self |
| 107 | + class(field_t), intent(inout) :: du, dv, dw |
| 108 | + class(field_t), intent(in) :: u, v, w |
| 109 | + type(dirps_t), intent(in) :: dirps |
| 110 | + |
| 111 | + !call self%transeq_omp_dist(du, dv, dw, u, v, w, dirps) |
| 112 | + |
| 113 | + end subroutine transeq_x_omp |
| 114 | + |
| 115 | + subroutine transeq_y_omp(self, du, dv, dw, u, v, w, dirps) |
| 116 | + implicit none |
| 117 | + |
| 118 | + class(omp_backend_t) :: self |
| 119 | + class(field_t), intent(inout) :: du, dv, dw |
| 120 | + class(field_t), intent(in) :: u, v, w |
| 121 | + type(dirps_t), intent(in) :: dirps |
| 122 | + |
| 123 | + ! u, v, w is reordered so that we pass v, u, w |
| 124 | + !call self%transeq_omp_dist(dv, du, dw, v, u, w, dirps) |
| 125 | + |
| 126 | + end subroutine transeq_y_omp |
| 127 | + |
| 128 | + subroutine transeq_z_omp(self, du, dv, dw, u, v, w, dirps) |
| 129 | + implicit none |
| 130 | + |
| 131 | + class(omp_backend_t) :: self |
| 132 | + class(field_t), intent(inout) :: du, dv, dw |
| 133 | + class(field_t), intent(in) :: u, v, w |
| 134 | + type(dirps_t), intent(in) :: dirps |
| 135 | + |
| 136 | + ! u, v, w is reordered so that we pass w, u, v |
| 137 | + !call self%transeq_omp_dist(dw, du, dv, w, u, v, dirps) |
| 138 | + |
| 139 | + end subroutine transeq_z_omp |
| 140 | + |
| 141 | + subroutine trans_x2y_omp(self, u_, v_, w_, u, v, w) |
| 142 | + implicit none |
| 143 | + |
| 144 | + class(omp_backend_t) :: self |
| 145 | + class(field_t), intent(inout) :: u_, v_, w_ |
| 146 | + class(field_t), intent(in) :: u, v, w |
| 147 | + |
| 148 | + end subroutine trans_x2y_omp |
| 149 | + |
| 150 | + subroutine trans_x2z_omp(self, u_, v_, w_, u, v, w) |
| 151 | + implicit none |
| 152 | + |
| 153 | + class(omp_backend_t) :: self |
| 154 | + class(field_t), intent(inout) :: u_, v_, w_ |
| 155 | + class(field_t), intent(in) :: u, v, w |
| 156 | + |
| 157 | + end subroutine trans_x2z_omp |
| 158 | + |
| 159 | + subroutine sum_yzintox_omp(self, du, dv, dw, & |
| 160 | + du_y, dv_y, dw_y, du_z, dv_z, dw_z) |
| 161 | + implicit none |
| 162 | + |
| 163 | + class(omp_backend_t) :: self |
| 164 | + class(field_t), intent(inout) :: du, dv, dw |
| 165 | + class(field_t), intent(in) :: du_y, dv_y, dw_y, du_z, dv_z, dw_z |
| 166 | + |
| 167 | + end subroutine sum_yzintox_omp |
| 168 | + |
| 169 | + subroutine copy_into_buffers(u_send_s, u_send_e, u, n) |
| 170 | + implicit none |
| 171 | + |
| 172 | + real(dp), dimension(:, :, :), intent(out) :: u_send_s, u_send_e |
| 173 | + real(dp), dimension(:, :, :), intent(in) :: u |
| 174 | + integer, intent(in) :: n |
| 175 | + |
| 176 | + u_send_s(:, :, :) = u(:, 1:4, :) |
| 177 | + u_send_e(:, :, :) = u(:, n - 3:n, :) |
| 178 | + |
| 179 | + end subroutine copy_into_buffers |
| 180 | + |
| 181 | + subroutine set_fields_omp(self, u, v, w, u_in, v_in, w_in) |
| 182 | + implicit none |
| 183 | + |
| 184 | + class(omp_backend_t) :: self |
| 185 | + class(field_t), intent(inout) :: u, v, w |
| 186 | + real(dp), dimension(:, :, :), intent(in) :: u_in, v_in, w_in |
| 187 | + |
| 188 | + u%data = u_in |
| 189 | + v%data = v_in |
| 190 | + w%data = w_in |
| 191 | + |
| 192 | + end subroutine set_fields_omp |
| 193 | + |
| 194 | + subroutine get_fields_omp(self, u_out, v_out, w_out, u, v, w) |
| 195 | + implicit none |
| 196 | + |
| 197 | + class(omp_backend_t) :: self |
| 198 | + real(dp), dimension(:, :, :), intent(out) :: u_out, v_out, w_out |
| 199 | + class(field_t), intent(in) :: u, v, w |
| 200 | + |
| 201 | + u_out = u%data |
| 202 | + v_out = v%data |
| 203 | + w_out = w%data |
| 204 | + |
| 205 | + end subroutine get_fields_omp |
| 206 | + |
| 207 | +end module m_omp_backend |
| 208 | + |
0 commit comments