53 ut_init_transposition, &
56 USE ftest_common
, ONLY: finish_mpi, icmp, id_map, factorize, regular_deco
60 INTEGER,
PARAMETER :: g_ie = 8, g_je = 4
61 LOGICAL,
PARAMETER :: verbose = .false.
62 INTEGER,
PARAMETER :: nlev = 3
63 INTEGER,
PARAMETER :: undef_int = g_ie * g_je * nlev + 1
64 INTEGER(xt_int_kind),
PARAMETER :: undef_index = -1
65 INTEGER,
PARAMETER :: nhalo = 1
68 INTEGER :: p_ioff, p_joff
69 INTEGER :: nprocx, nprocy
72 INTEGER :: mype, mypx, mypy
75 INTEGER(xt_int_kind) :: g_id(g_ie, g_je)
78 INTEGER(xt_int_kind) :: g_tpex(g_ie, g_je)
79 INTEGER :: template_tpex, trans_tpex
81 INTEGER(xt_int_kind),
ALLOCATABLE :: loc_id(:,:), loc_tpex(:,:)
82 INTEGER,
ALLOCATABLE :: fval(:,:), gval(:,:)
83 INTEGER,
ALLOCATABLE :: gval3d(:,:,:)
84 INTEGER,
ALLOCATABLE :: id_pos(:,:), pos3d_surf(:,:)
85 INTEGER :: surf_trans_tpex
94 CALL get_window(g_id, loc_id)
97 CALL def_exchange(g_id, g_tpex)
100 CALL get_window(g_tpex, loc_tpex)
103 CALL gen_template(loc_id, loc_tpex, template_tpex)
106 CALL gen_trans(template_tpex, mpi_integer, mpi_integer, trans_tpex)
110 CALL exchange2d_2d(trans_tpex, fval, gval)
111 CALL icmp(
'2d to 2d check', gval, int(loc_tpex), mype)
114 CALL gen_id_pos(id_pos)
115 CALL gen_id_pos(pos3d_surf)
116 CALL gen_pos3d_surf(pos3d_surf)
119 CALL gen_off_trans(template_tpex, mpi_integer, id_pos(:,:)-1, &
120 mpi_integer, pos3d_surf(:,:)-1, surf_trans_tpex)
124 CALL exchange2d_3d(surf_trans_tpex, fval, gval3d)
125 CALL icmp(
'surface check', gval3d(:,1,:), int(loc_tpex), mype)
128 CALL icmp(
'sub surface check', gval3d(:,2,:), int(loc_tpex)*0-1, mype)
140 SUBROUTINE gen_pos3d_surf(pos)
141 INTEGER,
INTENT(inout) :: pos(:,:)
145 INTEGER :: ii,jj, i,j,k, p,q
153 q = i + k*ie + j*ie*nlev
158 END SUBROUTINE gen_pos3d_surf
161 CHARACTER(len=*),
PARAMETER :: context =
'init_all: ' 164 CALL mpi_init(ierror)
165 IF (ierror /= mpi_success)
CALL ut_abort(context//
'MPI_INIT failed', &
169 CALL mpi_comm_size(mpi_comm_world, nprocs, ierror)
170 IF (ierror /= mpi_success)
CALL ut_abort(context//
'MPI_COMM_SIZE failed', &
174 CALL mpi_comm_rank(mpi_comm_world, mype, ierror)
175 IF (ierror /= mpi_success)
CALL ut_abort(context//
'MPI_COMM_RANK failed', &
184 CALL factorize(nprocs, nprocx, nprocy)
185 IF (verbose .AND. lroot)
WRITE(0,*)
'nprocx, nprocy=',nprocx, nprocy
187 mypx = mod(mype, nprocx)
189 CALL ut_init(decomp_size=30, comm_tmpl_size=30, comm_size=30, &
194 ALLOCATE(fval(ie,je), gval(ie,je))
195 ALLOCATE(loc_id(ie,je), loc_tpex(ie,je))
196 ALLOCATE(id_pos(ie,je), gval3d(ie,nlev,je), pos3d_surf(ie,je))
204 pos3d_surf = undef_int
206 END SUBROUTINE init_all
208 SUBROUTINE gen_id_pos(pos)
209 INTEGER,
INTENT(out) :: pos(:,:)
215 DO j = 1,
SIZE(pos,2)
216 DO i = 1,
SIZE(pos,1)
222 END SUBROUTINE gen_id_pos
225 SUBROUTINE exchange2d_2d(itrans, f, g)
226 INTEGER,
INTENT(in) :: itrans
227 INTEGER,
TARGET,
INTENT(in) :: f(:,:)
228 INTEGER,
TARGET,
INTENT(out) :: g(:,:)
230 INTEGER,
POINTER :: p_in, p_out
237 END SUBROUTINE exchange2d_2d
239 SUBROUTINE exchange2d_3d(itrans, f, g)
240 INTEGER,
INTENT(in) :: itrans
241 INTEGER,
TARGET,
INTENT(in) :: f(:,:)
242 INTEGER,
TARGET,
INTENT(out) :: g(:,:,:)
244 INTEGER,
POINTER :: p_in, p_out
251 END SUBROUTINE exchange2d_3d
253 SUBROUTINE gen_trans(itemp, send_dt, recv_dt, itrans)
254 INTEGER,
INTENT(in) :: itemp, send_dt, recv_dt
255 INTEGER,
INTENT(out) :: itrans
259 IF (send_dt /= recv_dt) &
260 CALL ut_abort(
'gen_trans: (send_dt /= recv_dt) unsupported', &
264 CALL ut_init_transposition(itemp, dt, itrans)
266 END SUBROUTINE gen_trans
268 SUBROUTINE gen_off_trans(itemp, send_dt, send_off, recv_dt, recv_off, itrans)
269 INTEGER,
INTENT(in) :: itemp, send_dt, recv_dt
270 INTEGER,
INTENT(in) :: send_off(:,:), recv_off(:,:)
271 INTEGER,
INTENT(out) :: itrans
273 INTEGER :: send_offsets(size(send_off)), recv_offsets(size(recv_off))
275 send_offsets = reshape(send_off, (/
SIZE(send_off)/) )
276 recv_offsets = reshape(recv_off, (/
SIZE(recv_off)/) )
278 CALL ut_init_transposition(itemp, send_offsets, recv_offsets, &
279 send_dt, recv_dt, itrans)
281 END SUBROUTINE gen_off_trans
283 SUBROUTINE get_window(gval, win)
284 INTEGER(xt_int_kind),
INTENT(in) :: gval(:,:)
285 INTEGER(xt_int_kind),
INTENT(out) :: win(:,:)
287 INTEGER :: i, j, ig, jg
293 win(i,j) = gval(ig,jg)
297 END SUBROUTINE get_window
299 SUBROUTINE gen_template(local_src_idx, local_dst_idx, ihandle)
300 INTEGER(xt_int_kind),
INTENT(in) :: local_src_idx(:,:)
301 INTEGER(xt_int_kind),
INTENT(in) :: local_dst_idx(:,:)
302 INTEGER,
INTENT(out) :: ihandle
304 INTEGER :: src(size(local_src_idx)), dst(size(local_dst_idx))
306 INTEGER :: src_handle, dst_handle
308 src = reshape( local_src_idx, (/
SIZE(local_src_idx)/) )
309 dst = reshape( local_dst_idx, (/
SIZE(local_dst_idx)/) )
311 CALL ut_init_decomposition(src, g_ie * g_je, src_handle)
312 CALL ut_init_decomposition(dst, g_ie * g_je, dst_handle)
315 mpi_comm_world, ihandle)
320 END SUBROUTINE gen_template
322 SUBROUTINE def_exchange(id_in, id_out)
323 INTEGER(xt_int_kind),
INTENT(in) :: id_in(:,:)
324 INTEGER(xt_int_kind),
INTENT(out) :: id_out(:,:)
326 LOGICAL,
PARAMETER :: increased_north_halo = .false.
327 LOGICAL,
PARAMETER :: with_north_halo = .true.
329 INTEGER :: g_core_is, g_core_ie, g_core_js, g_core_je
330 INTEGER :: north_halo
333 g_core_is = nhalo + 1
334 g_core_ie = g_ie-nhalo
335 g_core_js = nhalo + 1
336 g_core_je = g_je-nhalo
340 id_out(g_core_is:g_core_ie, g_core_js:g_core_je) &
341 = id_in(g_core_is:g_core_ie, g_core_js:g_core_je)
343 IF (with_north_halo)
THEN 346 IF (increased_north_halo)
THEN 352 IF (2*north_halo > g_core_je) &
353 CALL ut_abort(
'def_exchange: grid too small (or halo too large)& 354 & for tripolar north exchange', &
358 DO i = g_core_is, g_core_ie
359 id_out(i,j) = id_out(g_core_ie + (g_core_is-i), 2*north_halo + (1-j))
366 DO i = nhalo+1, g_ie-nhalo
367 id_out(i,j) = id_in(i,j)
374 DO j = g_core_je+1, g_je
375 DO i = nhalo+1, g_ie-nhalo
376 id_out(i,j) = id_in(i,j)
383 id_out(g_core_is-i,j) = id_out(g_core_ie+(1-i),j)
386 id_out(g_core_ie+i,j) = id_out(nhalo+i,j)
390 CALL check_g_idx(id_out)
392 END SUBROUTINE def_exchange
394 SUBROUTINE check_g_idx(gidx)
395 INTEGER(xt_int_kind),
INTENT(in) :: gidx(:,:)
397 IF (any(gidx == undef_index))
THEN 398 CALL ut_abort(
'check_g_idx: check failed', __file__, __line__)
400 END SUBROUTINE check_g_idx
403 INTEGER :: cx0(0:nprocx-1), cxn(0:nprocx-1)
404 INTEGER :: cy0(0:nprocy-1), cyn(0:nprocy-1)
406 CALL regular_deco(g_ie-2*nhalo, cx0, cxn)
407 CALL regular_deco(g_je-2*nhalo, cy0, cyn)
410 ie = cxn(mypx) + 2*nhalo
411 je = cyn(mypy) + 2*nhalo