48 PROGRAM test_perf_stripes
56 USE ftest_common
, ONLY: finish_mpi, init_mpi, timer, treset, tstart, &
57 tstop, treport, id_map, test_abort, icmp, factorize, regular_deco
69 INTEGER,
PARAMETER :: nlev = 20
70 INTEGER,
PARAMETER :: undef_int = - 1
71 INTEGER(xt_int_kind),
PARAMETER :: undef_index = -1
72 INTEGER,
PARAMETER :: nhalo = 1
74 INTEGER,
PARAMETER :: grid_kind_test = 1
75 INTEGER,
PARAMETER :: grid_kind_toy = 2
76 INTEGER,
PARAMETER :: grid_kind_tp10 = 3
77 INTEGER,
PARAMETER :: grid_kind_tp04 = 4
78 INTEGER,
PARAMETER :: grid_kind_tp6m = 5
79 INTEGER :: grid_kind = grid_kind_test
81 CHARACTER(len=10) :: grid_label
84 INTEGER :: p_ioff, p_joff
85 INTEGER :: nprocx, nprocy
88 INTEGER :: mype, mypx, mypy
91 INTEGER,
ALLOCATABLE :: g_id(:,:)
93 INTEGER,
ALLOCATABLE :: g_tpex(:, :)
94 TYPE(xt_xmap) :: xmap_tpex_2d, xmap_tpex_3d, xmap_tpex_3d_ws
95 TYPE(xt_redist) :: redist_tpex_2d, redist_surf_tpex_2d, redist_tpex_3d, &
96 redist_tpex_3d_ws, redist_tpex_3d_wb
97 TYPE(xt_idxlist) :: loc_id_3d_ws, loc_tpex_3d_ws
99 INTEGER(xt_int_kind),
ALLOCATABLE :: loc_id_2d(:,:), loc_tpex_2d(:,:)
100 INTEGER(xt_int_kind),
ALLOCATABLE :: loc_id_3d(:,:,:), loc_tpex_3d(:,:,:)
101 INTEGER,
ALLOCATABLE :: fval_2d(:,:), gval_2d(:,:)
102 INTEGER,
ALLOCATABLE :: fval_3d(:,:,:), gval_3d(:,:,:)
103 INTEGER,
ALLOCATABLE :: id_pos(:,:), pos3d_surf(:,:)
104 LOGICAL,
PARAMETER :: full_test = .true.
107 TYPE(timer) :: t_all, t_surf_redist, t_exch_surf
108 TYPE(timer) :: t_xmap_2d, t_redist_2d, t_exch_2d
109 TYPE(timer) :: t_xmap_3d, t_redist_3d, t_exch_3d
110 TYPE(timer) :: t_xmap_3d_ws, t_redist_3d_ws, t_exch_3d_ws, t_exch_3d_wb
111 TYPE(timer) :: t_redist_3d_wb
115 CALL treset(t_all,
'all')
116 CALL treset(t_surf_redist,
'surf_redist')
117 CALL treset(t_exch_surf,
'exch_surf')
118 CALL treset(t_xmap_2d,
'xmap_2d')
119 CALL treset(t_redist_2d,
'redist_2d')
120 CALL treset(t_exch_2d,
'exch_2d')
121 CALL treset(t_xmap_3d,
'xmap_3d')
122 CALL treset(t_redist_3d,
'redist_3d')
123 CALL treset(t_exch_3d,
'exch_3d')
125 CALL treset(t_xmap_3d_ws,
'xmap_3d_ws')
126 CALL treset(t_redist_3d_ws,
'redist_3d_ws')
127 CALL treset(t_exch_3d_ws,
'exch_3d_ws')
129 CALL treset(t_redist_3d_wb,
'redist_3d_wb')
130 CALL treset(t_exch_3d_wb,
'exch_3d_wb')
139 ALLOCATE(fval_3d(nlev,ie,je), gval_3d(nlev,ie,je))
145 CALL get_window(g_id, loc_id_2d)
152 CALL get_window(g_tpex, loc_tpex_2d)
156 CALL tstart(t_xmap_2d)
157 CALL gen_xmap_2d(loc_id_2d, loc_tpex_2d, xmap_tpex_2d)
158 CALL tstop(t_xmap_2d)
161 CALL tstart(t_redist_2d)
162 CALL gen_redist(xmap_tpex_2d, mpi_integer, mpi_integer, redist_tpex_2d)
163 CALL tstop(t_redist_2d)
166 fval_2d = int(loc_id_2d)
167 CALL tstart(t_exch_2d)
169 CALL tstop(t_exch_2d)
170 CALL icmp(
'2d to 2d check', gval_2d, int(loc_tpex_2d), mype)
174 CALL id_map(pos3d_surf)
175 CALL gen_pos3d_surf(pos3d_surf)
178 CALL tstart(t_surf_redist)
179 CALL gen_off_redist(xmap_tpex_2d, mpi_integer, id_pos(:,:)-1, &
180 mpi_integer, pos3d_surf(:,:)-1, redist_surf_tpex_2d)
181 CALL tstop(t_surf_redist)
185 CALL tstart(t_exch_surf)
187 reshape(fval_2d, (/ 1, ie, je /)), gval_3d)
188 CALL tstop(t_exch_surf)
191 CALL icmp(
'surface check', gval_3d(1,:,:), int(loc_tpex_2d), mype)
195 CALL icmp(
'sub surface check', gval_3d(2,:,:), int(loc_tpex_2d)*0-1, mype)
200 CALL inflate_idx(1, loc_id_2d, loc_id_3d)
201 CALL inflate_idx(1, loc_tpex_2d, loc_tpex_3d)
206 CALL tstart(t_xmap_3d)
207 CALL gen_xmap_3d(loc_id_3d, loc_tpex_3d, xmap_tpex_3d)
208 CALL tstop(t_xmap_3d)
211 CALL tstart(t_redist_3d)
212 CALL gen_redist(xmap_tpex_3d, mpi_integer, mpi_integer, redist_tpex_3d)
213 CALL tstop(t_redist_3d)
219 fval_3d = int(loc_id_3d)
221 CALL tstart(t_exch_3d)
223 CALL tstop(t_exch_3d)
228 CALL icmp(
'3d to 3d check', gval_3d, int(loc_tpex_3d), mype)
233 CALL gen_stripes(loc_id_3d, loc_id_3d_ws)
234 CALL gen_stripes(loc_tpex_3d, loc_tpex_3d_ws)
239 CALL tstart(t_redist_3d_ws)
241 CALL tstop(t_redist_3d_ws)
244 fval_3d = int(loc_id_3d)
247 CALL tstart(t_exch_3d_ws)
249 CALL tstop(t_exch_3d_ws)
252 CALL icmp(
'3d to 3d check (using stripes)', gval_3d, int(loc_tpex_3d), mype)
255 CALL tstart(t_redist_3d_wb)
256 CALL gen_redist_3d_wb(xmap_tpex_2d, mpi_integer, redist_tpex_3d_wb)
257 CALL tstop(t_redist_3d_wb)
259 fval_3d = int(loc_id_3d)
261 CALL tstart(t_exch_3d_wb)
263 CALL tstop(t_exch_3d_wb)
267 CALL icmp(
'redist_tpex_3d_wb check', gval_3d, int(loc_tpex_3d), mype)
280 IF (verbose)
WRITE(0,*)
'timer report for nprocs=',nprocs
282 CALL treport(t_all, trim(grid_label), mpi_comm_world)
283 CALL treport(t_surf_redist, trim(grid_label), mpi_comm_world)
284 CALL treport(t_exch_surf, trim(grid_label), mpi_comm_world)
285 CALL treport(t_xmap_2d, trim(grid_label), mpi_comm_world)
286 CALL treport(t_redist_2d, trim(grid_label), mpi_comm_world)
287 CALL treport(t_exch_2d, trim(grid_label), mpi_comm_world)
288 CALL treport(t_xmap_3d, trim(grid_label), mpi_comm_world)
289 CALL treport(t_redist_3d, trim(grid_label), mpi_comm_world)
290 CALL treport(t_exch_3d, trim(grid_label), mpi_comm_world)
292 CALL treport(t_xmap_3d_ws, trim(grid_label), mpi_comm_world)
293 CALL treport(t_redist_3d_ws, trim(grid_label), mpi_comm_world)
294 CALL treport(t_exch_3d_ws, trim(grid_label), mpi_comm_world)
296 CALL treport(t_redist_3d_wb, trim(grid_label), mpi_comm_world)
297 CALL treport(t_exch_3d_wb, trim(grid_label), mpi_comm_world)
304 SUBROUTINE gen_redist_3d_wb(xmap_2d, dt, redist_3d)
305 TYPE(xt_xmap),
INTENT(in) :: xmap_2d
306 INTEGER,
INTENT(in) :: dt
307 TYPE(xt_redist),
INTENT(out) :: redist_3d
309 INTEGER :: block_disp(ie,je), block_size(ie,je)
314 block_disp(i,j) = ( (j-1) * ie + i - 1 ) * nlev
315 block_size(i,j) = nlev
320 SIZE(block_size), block_disp, block_size,
SIZE(block_size),dt)
322 END SUBROUTINE gen_redist_3d_wb
325 CHARACTER(len=*),
INTENT(in) :: s
326 IF (verbose)
WRITE(0,*) s
329 SUBROUTINE inflate_idx(inflate_pos, idx_2d, idx_3d)
330 CHARACTER(len=*),
PARAMETER :: context =
'test_perf::inflate_idx: ' 331 INTEGER,
INTENT(in) :: inflate_pos
332 INTEGER(xt_int_kind),
INTENT(in) :: idx_2d(:,:)
333 INTEGER(xt_int_kind),
ALLOCATABLE,
INTENT(out) :: idx_3d(:,:,:)
337 SELECT CASE(inflate_pos)
339 ALLOCATE(idx_3d(ke, ie, je))
343 idx_3d(k,i,j) = int(k + (idx_2d(i,j)-1) * ke, xt_int_kind)
348 ALLOCATE(idx_3d(ie, je, ke))
352 idx_3d(i,j,k) = int(idx_2d(i,j) + (k-1) * g_ie * g_je, xt_int_kind)
357 CALL test_abort(context//
' unsupported inflate position', &
362 END SUBROUTINE inflate_idx
364 SUBROUTINE gen_pos3d_surf(pos)
365 INTEGER,
INTENT(inout) :: pos(:,:)
371 INTEGER :: ii,jj, i,j,k, p,q
379 q = k + (i + j*ie)*nlev
384 END SUBROUTINE gen_pos3d_surf
387 CHARACTER(len=*),
PARAMETER :: context =
'init_all: ' 389 CHARACTER(len=20) :: grid_str
393 CALL get_environment_variable(
'YAXT_TEST_PERF_GRID', grid_str)
397 SELECT CASE (trim(adjustl(grid_str)))
399 grid_kind = grid_kind_toy
404 grid_kind = grid_kind_tp10
409 grid_kind = grid_kind_tp04
414 grid_kind = grid_kind_tp6m
419 grid_kind = grid_kind_test
426 CALL mpi_comm_size(mpi_comm_world, nprocs, ierror)
427 IF (ierror /= mpi_success) &
428 CALL test_abort(context//
'MPI_COMM_SIZE failed', &
432 CALL mpi_comm_rank(mpi_comm_world, mype, ierror)
433 IF (ierror /= mpi_success) &
434 CALL test_abort(context//
'MPI_COMM_RANK failed', &
444 CALL factorize(nprocs, nprocx, nprocy)
445 IF (lroot .AND. verbose)
WRITE(0,*)
'nprocx, nprocy=',nprocx, nprocy
446 IF (lroot .AND. verbose)
WRITE(0,*)
'g_ie, g_je=',g_ie, g_je
448 mypx = mod(mype, nprocx)
453 ALLOCATE(g_id(g_ie, g_je), g_tpex(g_ie, g_je))
455 ALLOCATE(fval_2d(ie,je), gval_2d(ie,je))
456 ALLOCATE(loc_id_2d(ie,je), loc_tpex_2d(ie,je))
457 ALLOCATE(id_pos(ie,je), pos3d_surf(ie,je))
461 loc_id_2d = int(undef_int, xt_int_kind)
462 loc_tpex_2d = int(undef_int, xt_int_kind)
464 pos3d_surf = undef_int
466 END SUBROUTINE init_all
468 SUBROUTINE gen_redist(xmap, send_dt, recv_dt, redist)
469 TYPE(xt_xmap),
INTENT(in) :: xmap
470 INTEGER,
INTENT(in) :: send_dt, recv_dt
471 TYPE(xt_redist),
INTENT(out) :: redist
475 IF (send_dt /= recv_dt) &
476 CALL test_abort(
'gen_redist: (send_dt /= recv_dt) unsupported', &
482 END SUBROUTINE gen_redist
484 SUBROUTINE gen_off_redist(xmap, send_dt, send_off, recv_dt, recv_off, redist)
485 TYPE(xt_xmap),
INTENT(in) :: xmap
486 INTEGER,
INTENT(in) :: send_dt, recv_dt
487 INTEGER,
INTENT(in) :: send_off(:,:), recv_off(:,:)
488 TYPE(xt_redist),
INTENT(out) :: redist
492 IF (send_dt /= recv_dt) &
493 CALL test_abort(
'gen_off_redist: (send_dt /= recv_dt) unsupported', &
499 END SUBROUTINE gen_off_redist
501 SUBROUTINE get_window(gval, win)
502 INTEGER,
INTENT(in) :: gval(:,:)
503 INTEGER(xt_int_kind),
INTENT(out) :: win(:,:)
505 INTEGER :: i, j, ig, jg
511 win(i,j) = int(gval(ig,jg), xt_int_kind)
515 END SUBROUTINE get_window
517 SUBROUTINE gen_stripes(local_idx, local_stripes)
518 CHARACTER(len=*),
PARAMETER :: context =
'gen_stripes: ' 520 INTEGER(xt_int_kind),
INTENT(in) :: local_idx(:,:,:)
521 TYPE(xt_idxlist),
INTENT(out) :: local_stripes
523 TYPE(
xt_stripe),
ALLOCATABLE :: stripes(:,:)
524 INTEGER :: i, j, k, ni, nj, nk
527 nk =
SIZE(local_idx,1)
528 ni =
SIZE(local_idx,2)
529 nj =
SIZE(local_idx,3)
531 ALLOCATE(stripes(ni,nj))
536 stripes(i,j) =
xt_stripe(local_idx(1,i,j), 1_xt_int_kind, nk)
538 IF (local_idx(1,i,j)-1+k /= local_idx(k,i,j)) &
539 CALL test_abort(context//
'stripe condition violated', &
548 END SUBROUTINE gen_stripes
550 SUBROUTINE gen_xmap_2d(local_src_idx, local_dst_idx, xmap)
551 INTEGER(xt_int_kind),
INTENT(in) :: local_src_idx(:,:)
552 INTEGER(xt_int_kind),
INTENT(in) :: local_dst_idx(:,:)
553 TYPE(xt_xmap),
INTENT(out) :: xmap
555 TYPE(xt_idxlist) :: src_idxlist, dst_idxlist
557 src_idxlist =
xt_idxvec_new(local_src_idx,
SIZE(local_src_idx))
558 dst_idxlist =
xt_idxvec_new(local_dst_idx,
SIZE(local_dst_idx))
564 END SUBROUTINE gen_xmap_2d
566 SUBROUTINE gen_xmap_3d(local_src_idx, local_dst_idx, xmap)
567 INTEGER(xt_int_kind),
INTENT(in) :: local_src_idx(:,:,:)
568 INTEGER(xt_int_kind),
INTENT(in) :: local_dst_idx(:,:,:)
569 TYPE(xt_xmap),
INTENT(out) :: xmap
571 TYPE(xt_idxlist) :: src_idxlist, dst_idxlist
573 src_idxlist =
xt_idxvec_new(local_src_idx,
SIZE(local_src_idx))
574 dst_idxlist =
xt_idxvec_new(local_dst_idx,
SIZE(local_dst_idx))
580 END SUBROUTINE gen_xmap_3d
582 SUBROUTINE def_exchange()
584 LOGICAL,
PARAMETER :: increased_north_halo = .false.
585 LOGICAL,
PARAMETER :: with_north_halo = .true.
587 INTEGER :: g_core_is, g_core_ie, g_core_js, g_core_je
588 INTEGER :: north_halo
591 g_core_is = nhalo + 1
592 g_core_ie = g_ie-nhalo
593 g_core_js = nhalo + 1
594 g_core_je = g_je-nhalo
598 g_tpex(g_core_is:g_core_ie, g_core_js:g_core_je) &
599 = g_id(g_core_is:g_core_ie, g_core_js:g_core_je)
601 IF (with_north_halo)
THEN 604 IF (increased_north_halo)
THEN 610 IF (2*north_halo > g_core_je) &
611 CALL test_abort(
'def_exchange: grid too small (or halo too large& 612 &) for tripolar north exchange', &
616 DO i = g_core_is, g_core_ie
617 g_tpex(i,j) = g_tpex(g_core_ie + (g_core_is-i), 2*north_halo + (1-j))
624 DO i = nhalo+1, g_ie-nhalo
625 g_tpex(i,j) = g_id(i,j)
632 DO j = g_core_je+1, g_je
633 DO i = nhalo+1, g_ie-nhalo
634 g_tpex(i,j) = g_id(i,j)
641 g_tpex(g_core_is-i,j) = g_tpex(g_core_ie+(1-i),j)
644 g_tpex(g_core_ie+i,j) = g_tpex(nhalo+i,j)
648 CALL check_g_idx (g_tpex)
650 END SUBROUTINE def_exchange
652 SUBROUTINE check_g_idx(gidx)
653 INTEGER,
INTENT(in) :: gidx(:,:)
655 IF (any(gidx == undef_index))
THEN 656 CALL test_abort(
'check_g_idx: check failed', __file__, __line__)
658 END SUBROUTINE check_g_idx
661 INTEGER :: cx0(0:nprocx-1), cxn(0:nprocx-1)
662 INTEGER :: cy0(0:nprocy-1), cyn(0:nprocy-1)
666 CALL regular_deco(g_ie-2*nhalo, cx0, cxn)
670 CALL regular_deco(g_je-2*nhalo, cy0, cyn)
673 ie = cxn(mypx) + 2*nhalo
674 je = cyn(mypy) + 2*nhalo
680 END PROGRAM test_perf_stripes