Yet Another eXchange Tool  DO_NOT_EDIT_HERE
test_perf_stripes.f90
1 
12 
13 !
14 ! Keywords:
15 ! Maintainer: Jörg Behrens <behrens@dkrz.de>
16 ! Moritz Hanke <hanke@dkrz.de>
17 ! Thomas Jahns <jahns@dkrz.de>
18 ! URL: https://doc.redmine.dkrz.de/yaxt/html/
19 !
20 ! Redistribution and use in source and binary forms, with or without
21 ! modification, are permitted provided that the following conditions are
22 ! met:
23 !
24 ! Redistributions of source code must retain the above copyright notice,
25 ! this list of conditions and the following disclaimer.
26 !
27 ! Redistributions in binary form must reproduce the above copyright
28 ! notice, this list of conditions and the following disclaimer in the
29 ! documentation and/or other materials provided with the distribution.
30 !
31 ! Neither the name of the DKRZ GmbH nor the names of its contributors
32 ! may be used to endorse or promote products derived from this software
33 ! without specific prior written permission.
34 !
35 ! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
36 ! IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
37 ! TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
38 ! PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
39 ! OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
40 ! EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
41 ! PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
42 ! PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
43 ! LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
44 ! NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
45 ! SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
46 !
47 
48 PROGRAM test_perf_stripes
49  USE mpi
50  USE yaxt, ONLY: xt_idxlist, xt_idxlist_delete, xt_idxvec_new, &
51  xt_xmap, xt_xmap_all2all_new, xt_xmap_delete, xt_redist, &
55 
56  USE ftest_common, ONLY: finish_mpi, init_mpi, timer, treset, tstart, &
57  tstop, treport, id_map, test_abort, icmp, factorize, regular_deco
58 
59  ! PGI compilers up to at least version 15 do not handle generic
60  ! interfaces correctly
61 #if defined __PGI
65 #endif
66  IMPLICIT NONE
67  ! global extents including halos:
68 
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 ! 1dim. halo border size
73 
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
80 
81  CHARACTER(len=10) :: grid_label
82  INTEGER :: g_ie, g_je ! global domain extents
83  INTEGER :: ie, je, ke ! local extents, including halos
84  INTEGER :: p_ioff, p_joff ! offsets within global domain
85  INTEGER :: nprocx, nprocy ! process space extents
86  INTEGER :: nprocs ! == nprocx*nprocy
87  ! process rank, process coords within (0:, 0:) process space
88  INTEGER :: mype, mypx, mypy
89  LOGICAL :: lroot ! true only for proc 0
90 
91  INTEGER, ALLOCATABLE :: g_id(:,:) ! global id
92  ! global "tripolar-like" toy bounds exchange
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
98 
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.
105  LOGICAL :: verbose
106 
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
112 
113  !WRITE(0,*) '(debug) test_perf_stripes: verbose=', verbose
114 
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')
124 
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')
128 
129  CALL treset(t_redist_3d_wb, 'redist_3d_wb')
130  CALL treset(t_exch_3d_wb, 'exch_3d_wb')
131 
132  CALL init_mpi
133 
134  CALL tstart(t_all)
135 
136  ! mpi & decomposition & allocate mem:
137  CALL init_all
138 
139  ALLOCATE(fval_3d(nlev,ie,je), gval_3d(nlev,ie,je))
140 
141  ! full global index space:
142  CALL id_map(g_id)
143 
144  ! local window of global index space:
145  CALL get_window(g_id, loc_id_2d)
146 
147  ! define bounds exchange for full global index space
148  CALL def_exchange()
149  !g_tpex = g_id
150 
151  ! local window of global bounds exchange:
152  CALL get_window(g_tpex, loc_tpex_2d)
153 
154  IF (full_test) THEN
155  ! xmap: loc_id_2d -> 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)
159 
160  ! transposition: loc_id_2d:data -> loc_tpex_2d:data
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)
164 
165  ! test 2d-to-2d transposition:
166  fval_2d = int(loc_id_2d)
167  CALL tstart(t_exch_2d)
168  CALL xt_redist_s_exchange(redist_tpex_2d, fval_2d, gval_2d)
169  CALL tstop(t_exch_2d)
170  CALL icmp('2d to 2d check', gval_2d, int(loc_tpex_2d), mype)
171 
172  ! define positions of surface elements within (k,i,j) array
173  CALL id_map(id_pos)
174  CALL id_map(pos3d_surf)
175  CALL gen_pos3d_surf(pos3d_surf)
176 
177  ! generate surface transposition:
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)
182 
183  ! 2d to surface boundsexchange:
184  gval_3d = -1
185  CALL tstart(t_exch_surf)
186  CALL xt_redist_s_exchange(redist_surf_tpex_2d, &
187  reshape(fval_2d, (/ 1, ie, je /)), gval_3d)
188  CALL tstop(t_exch_surf)
189 
190  ! check surface:
191  CALL icmp('surface check', gval_3d(1,:,:), int(loc_tpex_2d), mype)
192 
193  IF (nlev>1) THEN
194  ! check sub surface:
195  CALL icmp('sub surface check', gval_3d(2,:,:), int(loc_tpex_2d)*0-1, mype)
196  ENDIF
197  endif
198 
199  ! inflate (i,j) -> (k,i,j)
200  CALL inflate_idx(1, loc_id_2d, loc_id_3d)
201  CALL inflate_idx(1, loc_tpex_2d, loc_tpex_3d)
202 
203  IF (full_test) THEN
204 
205  ! xmap: loc_id_3d -> 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)
209 
210  ! transposition: loc_id_3d:data -> loc_tpex_3d:data
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)
214 
215  CALL xt_xmap_delete(xmap_tpex_3d)
216 
217  ! test 3d-to-3d transposition:
218  !DEALLOCATE(gval_3d)
219  fval_3d = int(loc_id_3d)
220  gval_3d = -1
221  CALL tstart(t_exch_3d)
222  CALL xt_redist_s_exchange(redist_tpex_3d, fval_3d, gval_3d)
223  CALL tstop(t_exch_3d)
224 
225  CALL xt_redist_delete(redist_tpex_3d)
226 
227  ! check 3d exchange:
228  CALL icmp('3d to 3d check', gval_3d, int(loc_tpex_3d), mype)
229  endif
230 
231 
232  ! gen stripes, xmap, redist:
233  CALL gen_stripes(loc_id_3d, loc_id_3d_ws)
234  CALL gen_stripes(loc_tpex_3d, loc_tpex_3d_ws)
235 
236  xmap_tpex_3d_ws = xt_xmap_all2all_new(loc_id_3d_ws, loc_tpex_3d_ws, &
237  mpi_comm_world)
238 
239  CALL tstart(t_redist_3d_ws)
240  redist_tpex_3d_ws = xt_redist_p2p_new(xmap_tpex_3d_ws, mpi_integer)
241  CALL tstop(t_redist_3d_ws)
242 
243  ! test redist_tpex_3d_ws:
244  fval_3d = int(loc_id_3d)
245  gval_3d = -1
246 
247  CALL tstart(t_exch_3d_ws)
248  CALL xt_redist_s_exchange(redist_tpex_3d_ws, fval_3d, gval_3d)
249  CALL tstop(t_exch_3d_ws)
250  if (full_test) then
251  ! check 3d exchange:
252  CALL icmp('3d to 3d check (using stripes)', gval_3d, int(loc_tpex_3d), mype)
253  endif
254 
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)
258 
259  fval_3d = int(loc_id_3d)
260  gval_3d = -1
261  CALL tstart(t_exch_3d_wb)
262  CALL xt_redist_s_exchange(redist_tpex_3d_wb, fval_3d, gval_3d)
263  CALL tstop(t_exch_3d_wb)
264 
265  CALL xt_redist_delete(redist_tpex_3d_wb)
266 
267  CALL icmp('redist_tpex_3d_wb check', gval_3d, int(loc_tpex_3d), mype)
268 
269  ! cleanup:
270  IF (full_test) THEN
271  CALL xt_redist_delete(redist_tpex_3d_ws)
272  CALL xt_xmap_delete(xmap_tpex_3d_ws)
273  CALL xt_xmap_delete(xmap_tpex_2d)
274  CALL xt_redist_delete(redist_tpex_2d)
275  CALL xt_redist_delete(redist_surf_tpex_2d)
276  ENDIF
277 
278  CALL tstop(t_all)
279 
280  IF (verbose) WRITE(0,*) 'timer report for nprocs=',nprocs
281 
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)
291 
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)
295 
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)
298 
299  CALL xt_finalize()
300  CALL finish_mpi
301 
302 CONTAINS
303 
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
308 
309  INTEGER :: block_disp(ie,je), block_size(ie,je)
310  INTEGER :: i, j
311  ! data(k,i,j)
312  DO j = 1, je
313  DO i = 1, ie
314  block_disp(i,j) = ( (j-1) * ie + i - 1 ) * nlev
315  block_size(i,j) = nlev
316  ENDDO
317  ENDDO
318  !WRITE(0,*) '(gen_redist_3d_wb) call redist with field sizes =',ie*je
319  redist_3d = xt_redist_p2p_blocks_off_new(xmap_2d, block_disp, block_size, &
320  SIZE(block_size), block_disp, block_size, SIZE(block_size),dt)
321 
322  END SUBROUTINE gen_redist_3d_wb
323 
324  SUBROUTINE msg(s)
325  CHARACTER(len=*), INTENT(in) :: s
326  IF (verbose) WRITE(0,*) s
327  END SUBROUTINE msg
328 
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(:,:,:)
334 
335  INTEGER :: i, j, k
336 
337  SELECT CASE(inflate_pos)
338  CASE(1)
339  ALLOCATE(idx_3d(ke, ie, je))
340  DO j=1,je
341  DO i=1,ie
342  DO k=1,ke
343  idx_3d(k,i,j) = int(k + (idx_2d(i,j)-1) * ke, xt_int_kind)
344  ENDDO
345  ENDDO
346  ENDDO
347  CASE(3)
348  ALLOCATE(idx_3d(ie, je, ke))
349  DO k=1,ke
350  DO j=1,je
351  DO i=1,ie
352  idx_3d(i,j,k) = int(idx_2d(i,j) + (k-1) * g_ie * g_je, xt_int_kind)
353  ENDDO
354  ENDDO
355  ENDDO
356  CASE DEFAULT
357  CALL test_abort(context//' unsupported inflate position', &
358  __file__, &
359  __line__)
360  END SELECT
361 
362  END SUBROUTINE inflate_idx
363 
364  SUBROUTINE gen_pos3d_surf(pos)
365  INTEGER, INTENT(inout) :: pos(:,:)
366 
367  ! positions for zero based arrays ([k,i,j] dim order):
368  ! old pos = i + j*ie
369  ! new pos = k + (i + j*ie)*nlev
370 
371  INTEGER :: ii,jj, i,j,k, p,q
372 
373  k = 0 ! surface
374  DO jj=1,je
375  DO ii=1,ie
376  p = pos(ii,jj) - 1 ! shift to 0-based index
377  j = p/ie
378  i = mod(p,ie)
379  q = k + (i + j*ie)*nlev
380  pos(ii,jj) = q + 1 ! shift to 1-based index
381  ENDDO
382  ENDDO
383 
384  END SUBROUTINE gen_pos3d_surf
385 
386  SUBROUTINE init_all
387  CHARACTER(len=*), PARAMETER :: context = 'init_all: '
388  INTEGER :: ierror
389  CHARACTER(len=20) :: grid_str
390 
391  CALL xt_initialize(mpi_comm_world)
392 
393  CALL get_environment_variable('YAXT_TEST_PERF_GRID', grid_str)
394 
395  verbose = .true.
396 
397  SELECT CASE (trim(adjustl(grid_str)))
398  CASE('TOY')
399  grid_kind = grid_kind_toy
400  grid_label = 'TOY'
401  g_ie = 66
402  g_je = 36
403  CASE('TP10')
404  grid_kind = grid_kind_tp10
405  grid_label = 'TP10'
406  g_ie = 362
407  g_je = 192
408  CASE('TP04')
409  grid_kind = grid_kind_tp04
410  grid_label = 'TP04'
411  g_ie = 802
412  g_je = 404
413  CASE('TP6M')
414  grid_kind = grid_kind_tp6m
415  grid_label = 'TP6M'
416  g_ie = 3602
417  g_je = 2394
418  CASE default
419  grid_kind = grid_kind_test
420  grid_label = 'TEST'
421  g_ie = 32
422  g_je = 12
423  verbose = .false.
424  END SELECT
425 
426  CALL mpi_comm_size(mpi_comm_world, nprocs, ierror)
427  IF (ierror /= mpi_success) &
428  CALL test_abort(context//'MPI_COMM_SIZE failed', &
429  __file__, &
430  __line__)
431 
432  CALL mpi_comm_rank(mpi_comm_world, mype, ierror)
433  IF (ierror /= mpi_success) &
434  CALL test_abort(context//'MPI_COMM_RANK failed', &
435  __file__, &
436  __line__)
437  IF (mype==0) THEN
438  lroot = .true.
439  ELSE
440  lroot = .false.
441  verbose = .false.
442  ENDIF
443 
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
447  mypy = mype / nprocx
448  mypx = mod(mype, nprocx)
449 
450  CALL deco
451  ke = nlev
452 
453  ALLOCATE(g_id(g_ie, g_je), g_tpex(g_ie, g_je))
454 
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))
458 
459  fval_2d = undef_int
460  gval_2d = undef_int
461  loc_id_2d = int(undef_int, xt_int_kind)
462  loc_tpex_2d = int(undef_int, xt_int_kind)
463  id_pos = undef_int
464  pos3d_surf = undef_int
465 
466  END SUBROUTINE init_all
467 
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
472 
473  INTEGER :: dt
474 
475  IF (send_dt /= recv_dt) &
476  CALL test_abort('gen_redist: (send_dt /= recv_dt) unsupported', &
477  __file__, &
478  __line__)
479  dt = send_dt
480  redist = xt_redist_p2p_new(xmap, dt)
481 
482  END SUBROUTINE gen_redist
483 
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
489 
490  INTEGER :: dt
491 
492  IF (send_dt /= recv_dt) &
493  CALL test_abort('gen_off_redist: (send_dt /= recv_dt) unsupported', &
494  __file__, &
495  __line__)
496  dt = send_dt
497 
498  redist = xt_redist_p2p_off_new(xmap, send_off, recv_off, dt)
499  END SUBROUTINE gen_off_redist
500 
501  SUBROUTINE get_window(gval, win)
502  INTEGER, INTENT(in) :: gval(:,:)
503  INTEGER(xt_int_kind), INTENT(out) :: win(:,:)
504 
505  INTEGER :: i, j, ig, jg
506 
507  DO j = 1, je
508  jg = p_joff + j
509  DO i = 1, ie
510  ig = p_ioff + i
511  win(i,j) = int(gval(ig,jg), xt_int_kind)
512  ENDDO
513  ENDDO
514 
515  END SUBROUTINE get_window
516 
517  SUBROUTINE gen_stripes(local_idx, local_stripes)
518  CHARACTER(len=*), PARAMETER :: context = 'gen_stripes: '
519 
520  INTEGER(xt_int_kind), INTENT(in) :: local_idx(:,:,:)
521  TYPE(xt_idxlist), INTENT(out) :: local_stripes
522 
523  TYPE(xt_stripe), ALLOCATABLE :: stripes(:,:)
524  INTEGER :: i, j, k, ni, nj, nk
525 
526  ! FIXME: assert nk matches xt_int_kind representable values
527  nk = SIZE(local_idx,1)
528  ni = SIZE(local_idx,2)
529  nj = SIZE(local_idx,3)
530 
531  ALLOCATE(stripes(ni,nj))
532 
533  DO j = 1, nj
534  DO i = 1, ni
535  ! start, nstrides, stride
536  stripes(i,j) = xt_stripe(local_idx(1,i,j), 1_xt_int_kind, nk)
537  DO k = 1, nk
538  IF (local_idx(1,i,j)-1+k /= local_idx(k,i,j)) &
539  CALL test_abort(context//'stripe condition violated', &
540  __file__, &
541  __line__)
542  ENDDO
543  ENDDO
544  ENDDO
545 
546  local_stripes = xt_idxstripes_new(stripes, SIZE(stripes))
547 
548  END SUBROUTINE gen_stripes
549 
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
554 
555  TYPE(xt_idxlist) :: src_idxlist, dst_idxlist
556 
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))
559  xmap = xt_xmap_all2all_new(src_idxlist, dst_idxlist, mpi_comm_world)
560 
561  CALL xt_idxlist_delete(src_idxlist)
562  CALL xt_idxlist_delete(dst_idxlist)
563 
564  END SUBROUTINE gen_xmap_2d
565 
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
570 
571  TYPE(xt_idxlist) :: src_idxlist, dst_idxlist
572 
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))
575  xmap = xt_xmap_all2all_new(src_idxlist, dst_idxlist, mpi_comm_world)
576  CALL xt_idxlist_delete(src_idxlist)
577  CALL xt_idxlist_delete(dst_idxlist)
578 
579 
580  END SUBROUTINE gen_xmap_3d
581 
582  SUBROUTINE def_exchange()
583 
584  LOGICAL, PARAMETER :: increased_north_halo = .false.
585  LOGICAL, PARAMETER :: with_north_halo = .true.
586  INTEGER :: i, j
587  INTEGER :: g_core_is, g_core_ie, g_core_js, g_core_je
588  INTEGER :: north_halo
589 
590  ! global core domain:
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
595 
596  ! global tripolar boundsexchange:
597  g_tpex = undef_index
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)
600 
601  IF (with_north_halo) THEN
602 
603  ! north inversion, (maybe with increased north halo)
604  IF (increased_north_halo) THEN
605  north_halo = nhalo+1
606  ELSE
607  north_halo = nhalo
608  ENDIF
609 
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', &
613  __file__, &
614  __line__)
615  DO j = 1, north_halo
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))
618  ENDDO
619  ENDDO
620 
621  ELSE
622 
623  DO j = 1, nhalo
624  DO i = nhalo+1, g_ie-nhalo
625  g_tpex(i,j) = g_id(i,j)
626  ENDDO
627  ENDDO
628 
629  ENDIF
630 
631  ! south: no change
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)
635  ENDDO
636  ENDDO
637 
638  ! PBC
639  DO j = 1, g_je
640  DO i = 1, nhalo
641  g_tpex(g_core_is-i,j) = g_tpex(g_core_ie+(1-i),j)
642  ENDDO
643  DO i = 1, nhalo
644  g_tpex(g_core_ie+i,j) = g_tpex(nhalo+i,j)
645  ENDDO
646  ENDDO
647 
648  CALL check_g_idx (g_tpex)
649 
650  END SUBROUTINE def_exchange
651 
652  SUBROUTINE check_g_idx(gidx)
653  INTEGER,INTENT(in) :: gidx(:,:)
654 
655  IF (any(gidx == undef_index)) THEN
656  CALL test_abort('check_g_idx: check failed', __file__, __line__)
657  ENDIF
658  END SUBROUTINE check_g_idx
659 
660  SUBROUTINE deco
661  INTEGER :: cx0(0:nprocx-1), cxn(0:nprocx-1)
662  INTEGER :: cy0(0:nprocy-1), cyn(0:nprocy-1)
663 
664  cx0 = 0
665  cxn = 0
666  CALL regular_deco(g_ie-2*nhalo, cx0, cxn)
667 
668  cy0 = 0
669  cyn = 0
670  CALL regular_deco(g_je-2*nhalo, cy0, cyn)
671 
672  ! process local deco variables:
673  ie = cxn(mypx) + 2*nhalo
674  je = cyn(mypy) + 2*nhalo
675  p_ioff = cx0(mypx)
676  p_joff = cy0(mypy)
677 
678  END SUBROUTINE deco
679 
680 END PROGRAM test_perf_stripes
681 !
682 ! Local Variables:
683 ! f90-continuation-indent: 5
684 ! coding: utf-8
685 ! indent-tabs-mode: nil
686 ! show-trailing-whitespace: t
687 ! require-trailing-newline: t
688 ! End:
689 !