Yet Another eXchange Tool  DO_NOT_EDIT_HERE
test_xmap_intersection_parallel_f.f90
1 
13 ! Keywords:
14 ! Maintainer: Jörg Behrens <behrens@dkrz.de>
15 ! Moritz Hanke <hanke@dkrz.de>
16 ! Thomas Jahns <jahns@dkrz.de>
17 ! URL: https://doc.redmine.dkrz.de/yaxt/html/
18 !
19 ! Redistribution and use in source and binary forms, with or without
20 ! modification, are permitted provided that the following conditions are
21 ! met:
22 !
23 ! Redistributions of source code must retain the above copyright notice,
24 ! this list of conditions and the following disclaimer.
25 !
26 ! Redistributions in binary form must reproduce the above copyright
27 ! notice, this list of conditions and the following disclaimer in the
28 ! documentation and/or other materials provided with the distribution.
29 !
30 ! Neither the name of the DKRZ GmbH nor the names of its contributors
31 ! may be used to endorse or promote products derived from this software
32 ! without specific prior written permission.
33 !
34 ! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
35 ! IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
36 ! TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
37 ! PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
38 ! OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
39 ! EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
40 ! PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
41 ! PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
42 ! LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
43 ! NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
44 ! SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
45 PROGRAM test_xmap_intersection_parallel
46  USE ftest_common, ONLY: init_mpi, finish_mpi, test_abort
47  USE mpi
48  USE test_idxlist_utils, ONLY: test_err_count
49  USE yaxt, ONLY: xt_initialize, xt_finalize, xt_int_kind, &
50  xt_idxlist, xt_idxvec_new, xt_idxlist_delete, xt_xmap, &
51  xt_idxempty_new, xi => xt_int_kind, &
53  xt_xmap_copy, xt_xmap_delete, xt_xmap_iter, &
59 #if defined __PGI && ( __PGIC__ < 12 || (__PGIC__ == 12 && __PGIC_MINOR__ <= 7))
60  ! PGI Fortran 12.7 and older has a bug that prevents proper passing of
61  ! generic interfaces through multiple modules, direct USE instead
62  USE xt_xmap_abstract, ONLY: xt_is_null
63 #else
64  USE yaxt, ONLY: xt_is_null
65 #endif
66  IMPLICIT NONE
67 
68  TYPE test_message
69  INTEGER :: rank ! rank of communication partner
70  INTEGER, POINTER :: pos(:) ! positions to be sent/received
71  END TYPE test_message
72  INTERFACE
73  SUBROUTINE posix_exit(code) bind(c, name='exit')
74  USE iso_c_binding, ONLY: c_int
75  INTEGER(c_int), VALUE, INTENT(in) :: code
76  END SUBROUTINE posix_exit
77  END INTERFACE
78 
79  INTEGER, PARAMETER :: xmi_type_base = 0, xmi_type_ext = 1
80  INTEGER :: xmi_type
81 
82  INTEGER :: ierror
83  INTEGER :: my_rank, comm_size
84 
85  CALL init_mpi
86  CALL xt_initialize(mpi_comm_world)
87  xmi_type = xmi_type_base
88  CALL parse_options
89 
90  CALL mpi_comm_rank(mpi_comm_world, my_rank, ierror)
91  IF (ierror /= mpi_success) &
92  CALL test_abort("MPI error!", &
93  __file__, &
94  __line__)
95 
96  CALL mpi_comm_size(mpi_comm_world, comm_size, ierror)
97  IF (ierror /= mpi_success) &
98  CALL test_abort("MPI error!", &
99  __file__, &
100  __line__)
101 
102  IF (comm_size /= 3) THEN
103  CALL xt_finalize
104  CALL finish_mpi
105  CALL posix_exit(77)
106  END IF
107 
108  ! parse_options(&argc, &argv);
109  CALL simple_rr_test
110  CALL elimination_test
111  CALL one_to_one_comm_test
112  CALL full_comm_matrix_test
113  CALL dedup_test
114 
115  IF (test_err_count() /= 0) &
116  CALL test_abort("non-zero error count!", &
117  __file__, &
118  __line__)
119  CALL xt_finalize
120  CALL finish_mpi
121 
122 CONTAINS
123  ! simple test (round robin)
124  SUBROUTINE simple_rr_test
125  ! setup
126  INTEGER(xi) :: src_index(1), dst_index(1)
127  TYPE(xt_idxlist) :: src_idxlist, dst_idxlist
128  INTEGER, PARAMETER :: num_src_intersections = 1, &
129  num_dst_intersections = 1, num_sends = 1, num_recvs = 1
130  INTEGER, SAVE, TARGET :: send_pos(num_sends) = (/ 0 /), &
131  recv_pos(num_recvs) = (/ 0 /)
132  TYPE(xt_com_list) :: src_com(num_src_intersections), &
133  dst_com(num_dst_intersections)
134  TYPE(xt_xmap) :: xmap
135  TYPE(test_message) :: send_messages(1), recv_messages(1)
136 
137  src_index(1) = int(my_rank, xi)
138  dst_index(1) = int(mod(my_rank + 1, comm_size), xi)
139  src_idxlist = xt_idxvec_new(src_index)
140  dst_idxlist = xt_idxvec_new(dst_index)
141  src_com(1) = xt_com_list(src_idxlist, mod(my_rank+1, comm_size))
142  dst_com(1) = xt_com_list(dst_idxlist, mod(my_rank+comm_size-1, comm_size))
143 
144  xmap = xmi_new(src_com(1:num_src_intersections), &
145  dst_com(1:num_dst_intersections), &
146  src_idxlist, dst_idxlist, mpi_comm_world)
147 
148  ! test
149  send_messages(1)%rank = mod(my_rank+1, comm_size)
150  send_messages(1)%pos => send_pos
151  recv_messages(1)%rank = mod(my_rank+comm_size-1, comm_size)
152  recv_messages(1)%pos => recv_pos
153 
154  CALL test_xmap(xmap, send_messages, recv_messages)
155 
156  ! cleanup
157  CALL xt_xmap_delete(xmap)
158  CALL xt_idxlist_delete(dst_idxlist)
159  CALL xt_idxlist_delete(src_idxlist)
160  END SUBROUTINE simple_rr_test
161 
162  ! rank 0 receives the same point from rank 1 and 2
163  SUBROUTINE elimination_test
164  INTEGER(xi), PARAMETER :: src_index(1) = (/ 0_xi /), &
165  dst_index(1) = (/ 0_xi /)
166  TYPE(xt_idxlist) :: src_idxlist, dst_idxlist
167  INTEGER :: num_src_intersections, num_dst_intersections, num_sends, &
168  num_recvs
169  INTEGER, TARGET :: send_pos(1), recv_pos(1)
170  TYPE(xt_com_list) :: src_com(1), dst_com(2)
171  TYPE(xt_xmap) :: xmap
172  TYPE(test_message) :: send_messages(1), recv_messages(1)
173  ! setup
174  IF (my_rank == 0) THEN
175  src_idxlist = xt_idxempty_new()
176  dst_idxlist = xt_idxvec_new(dst_index)
177  ELSE
178  src_idxlist = xt_idxvec_new(src_index)
179  dst_idxlist = xt_idxempty_new()
180  END IF
181  num_src_intersections = merge(1, 0, my_rank /= 0)
182  src_com = xt_com_list(src_idxlist, 0)
183  num_dst_intersections = merge(0, 2, my_rank /= 0)
184  dst_com(1) = xt_com_list(dst_idxlist, 1)
185  dst_com(2) = xt_com_list(dst_idxlist, 2)
186 
187  xmap = xmi_new(src_com(1:num_src_intersections), &
188  dst_com(1:num_dst_intersections), &
189  src_idxlist, dst_idxlist, mpi_comm_world)
190 
191  ! test
192  send_pos(1) = 0
193  num_sends = merge(1, 0, my_rank == 1)
194  send_messages(1)%rank = 0
195  send_messages(1)%pos => send_pos
196  recv_pos(1) = 0;
197  num_recvs = merge(1, 0, my_rank == 0)
198  recv_messages(1)%rank = 1
199  recv_messages(1)%pos => recv_pos
200 
201  CALL test_xmap(xmap, send_messages(1:num_sends), recv_messages(1:num_recvs))
202 
203  ! cleanup
204 
205  CALL xt_xmap_delete(xmap)
206  CALL xt_idxlist_delete(dst_idxlist)
207  CALL xt_idxlist_delete(src_idxlist)
208  END SUBROUTINE elimination_test
209 
210  ! all ranks can receive data from one of the others
211  SUBROUTINE one_to_one_comm_test
212  ! rank | 0 | 1 | 2 |
213  ! source indices | 1,2 | 2,0 | 0,1 |
214  ! destination indice | 0 | 1 | 2 |
215 
216  INTEGER(xi) :: src_indices(2), dst_index(1)
217  TYPE(xt_idxlist) :: src_idxlist, dst_idxlist, src_intersection_idxlist(2)
218  INTEGER, PARAMETER :: num_src_intersections(3) = (/ 2, 1, 0 /)
219  INTEGER :: num_sends, num_recvs, s_s, s_e, i
220  INTEGER, TARGET :: send_pos(2), recv_pos(1)
221  TYPE(xt_com_list) :: src_com(2), dst_com(1)
222  TYPE(xt_xmap) :: xmap
223  TYPE(test_message) :: send_messages(2), recv_messages(1)
224  ! setup
225  dst_index(1) = int(my_rank, xi)
226  DO i = 1, 2
227  src_indices(i) = int(mod(my_rank+i, comm_size), xi)
228  src_intersection_idxlist(i) = xt_idxvec_new(src_indices(i:i), 1)
229  END DO
230  src_idxlist = xt_idxvec_new(src_indices, 2)
231  dst_idxlist = xt_idxvec_new(dst_index, 1)
232  src_com(1) = xt_com_list(src_intersection_idxlist(1), 1)
233  src_com(2) = xt_com_list(src_intersection_idxlist(2), &
234  merge(2, 0, my_rank == 0))
235  dst_com = xt_com_list(dst_idxlist, merge(1, 0, my_rank == 0))
236  s_s = merge(my_rank + 1, 1, my_rank /= 2)
237  s_e = s_s + num_src_intersections(my_rank + 1) - 1
238  xmap = xmi_new(src_com(s_s:s_e), dst_com(:), src_idxlist, dst_idxlist, &
239  mpi_comm_world)
240 
241  ! test
242  recv_pos(1) = 0
243  num_recvs = 1
244  SELECT CASE (my_rank)
245  CASE (0)
246  send_pos(1) = 0
247  send_pos(2) = 1
248  num_sends = 2
249  send_messages(1)%rank = 1
250  send_messages(1)%pos => send_pos(1:1)
251  send_messages(2)%rank = 2
252  send_messages(2)%pos => send_pos(2:2)
253  recv_messages(1)%rank = 1
254  CASE (1)
255  send_pos = 1
256  num_sends = 1
257  send_messages(1)%rank = 0
258  send_messages(1)%pos => send_pos(1:1)
259  recv_messages(1)%rank = 0
260  CASE default
261  num_sends = 0
262  recv_messages(1)%rank = 0
263  END SELECT
264  recv_messages(1)%pos => recv_pos(1:1)
265  CALL test_xmap(xmap, send_messages(1:num_sends), recv_messages(1:num_recvs))
266 
267  ! cleanup
268  CALL xt_xmap_delete(xmap)
269  CALL xt_idxlist_delete(src_intersection_idxlist(2))
270  CALL xt_idxlist_delete(src_intersection_idxlist(1))
271  CALL xt_idxlist_delete(dst_idxlist)
272  CALL xt_idxlist_delete(src_idxlist)
273  END SUBROUTINE one_to_one_comm_test
274 
275  ! all ranks receive data from each of the others
276  SUBROUTINE full_comm_matrix_test
277  !rank | 0 | 1 | 2
278  !source indices | 0,1,2,3,4 | 3,4,5,6,7 | 6,7,8,0,1
279  !destination indices|0,1,2,3,4,5,6,7,8|0,1,2,3,4,5,6,7,8|0,1,2,3,4,5,6,7,8
280 
281 
282  INTEGER(xi), PARAMETER :: src_indices(5,0:2) &
283  = reshape((/ 0_xi, 1_xi, 2_xi, 3_xi, 4_xi, &
284  & 3_xi, 4_xi ,5_xi, 6_xi, 7_xi, &
285  & 6_xi, 7_xi, 8_xi, 0_xi, 1_xi /), (/ 5, 3 /)), &
286  dst_indices(9) &
287  = (/ 0_xi, 1_xi, 2_xi, 3_xi, 4_xi, 5_xi, 6_xi, 7_xi, 8_xi /)
288  TYPE(xt_idxlist) :: src_idxlist, dst_idxlist
289  TYPE(xt_com_list) :: src_com(0:2), dst_com(0:2)
290  TYPE(xt_xmap) :: xmap
291  INTEGER, SAVE, TARGET :: send_pos(5, 0:2) &
292  = reshape((/ 0,1,2,3,4, 2,3,4,-1,-1, 2,-1,-1,-1,-1 /), (/ 5, 3 /)), &
293  num_send_pos(0:2) = (/ 5, 3, 1 /), &
294  recv_pos(5, 0:2) &
295  = reshape((/ 0,1,2,3,4, 5,6,7,-1,-1, 8,-1,-1,-1,-1 /), (/ 5, 3 /)), &
296  num_recv_pos(0:2) = (/ 5, 3, 1 /)
297  TYPE(test_message) :: send_messages(0:2), recv_messages(0:2)
298  INTEGER :: i
299 
300  ! setup
301  src_idxlist = xt_idxvec_new(src_indices(:, my_rank))
302  dst_idxlist = xt_idxvec_new(dst_indices, 9)
303  DO i = 0, 2
304  src_com(i) = xt_com_list(src_idxlist, i)
305  dst_com(i) = xt_com_list(xt_idxvec_new(src_indices(:, i)), i)
306  END DO
307  xmap = xmi_new(src_com, dst_com, src_idxlist, dst_idxlist, &
308  mpi_comm_world)
309 
310  ! test
311  DO i = 0, 2
312  send_messages(i)%rank = i
313  send_messages(i)%pos => send_pos(1:num_send_pos(my_rank), my_rank)
314  recv_messages(i)%rank = i
315  recv_messages(i)%pos => recv_pos(1:num_recv_pos(i), i)
316  END DO
317  CALL test_xmap(xmap, send_messages, recv_messages)
318 
319  ! cleanup
320  CALL xt_xmap_delete(xmap)
321  DO i = 2, 0, -1
322  CALL xt_idxlist_delete(dst_com(i)%list)
323  END DO
324  CALL xt_idxlist_delete(dst_idxlist)
325  CALL xt_idxlist_delete(src_idxlist)
326  END SUBROUTINE full_comm_matrix_test
327 
328  ! one rank receives data from the other two, that have duplicated indices
329  ! (this provokes a bug found by Joerg Behrens)
330  SUBROUTINE dedup_test
331  ! rank | 0 | 1 | 2 |
332  ! source indices | 0,2 | 1,2 | |
333  ! destination indices | | | 0,1,2 |
334 
335  INTEGER(xt_int_kind), PARAMETER :: src_indices(2, 0:1) &
336  = reshape((/ 0_xi,2_xi, 1_xi,2_xi /), (/ 2, 2 /))
337  TYPE(xt_com_list) :: src_com(1), dst_com(2)
338  INTEGER :: num_src_intersections, num_dst_intersections
339  TYPE(xt_idxlist) :: src_idxlist, dst_idxlist
340  INTEGER(xt_int_kind), PARAMETER :: dst_indices(3) = (/ 0_xi, 1_xi, 2_xi /)
341  TYPE(xt_xmap) :: xmap
342  INTEGER :: i, num_recv_messages, num_send_messages
343  INTEGER, PARAMETER :: num_recv_pos(2) = (/ 2, 1 /), &
344  num_send_pos(2) = (/ 2, 1 /)
345  INTEGER, SAVE, TARGET :: &
346  recv_pos(2, 2) = reshape((/ 0, 2, 1, -1 /), (/ 2, 2 /)), &
347  send_pos(2, 2) = reshape((/ 0, 1, 0, -1 /), (/ 2, 2 /))
348  TYPE(test_message) :: recv_messages(2), send_messages(1)
349  ! setup
350  IF (my_rank == 2) THEN
351  num_src_intersections = 0
352  num_dst_intersections = 2
353  DO i = 0, 1
354  dst_com(i+1)%list = xt_idxvec_new(src_indices(:, i))
355  dst_com(i+1)%rank = i
356  END DO
357  src_idxlist = xt_idxempty_new()
358  dst_idxlist = xt_idxvec_new(dst_indices(:))
359  ELSE
360  num_src_intersections = 1
361  src_com(1)%list = xt_idxvec_new(src_indices(:, my_rank))
362  src_com(1)%rank = 2
363  num_dst_intersections = 0;
364  src_idxlist = xt_idxvec_new(src_indices(:, my_rank))
365  dst_idxlist = xt_idxempty_new()
366  END IF
367  xmap = xmi_new(src_com(1:num_src_intersections), &
368  dst_com(1:num_dst_intersections), &
369  src_idxlist, dst_idxlist, mpi_comm_world)
370 
371  ! test
372  IF (my_rank == 2) THEN
373  num_recv_messages = 2
374  num_send_messages = 0
375  DO i = 1, 2
376  recv_messages(i)%rank = i - 1
377  recv_messages(i)%pos => recv_pos(1:num_recv_pos(i), i)
378  END DO
379  ELSE
380  num_recv_messages = 0
381  num_send_messages = 1
382  send_messages(1)%rank = 2
383  send_messages(1)%pos => send_pos(1:num_send_pos(my_rank + 1), my_rank + 1)
384  END IF
385  CALL test_xmap(xmap, send_messages(1:num_send_messages), &
386  recv_messages(1:num_recv_messages))
387 
388  ! cleanup
389  CALL xt_xmap_delete(xmap)
390  CALL xt_idxlist_delete(dst_idxlist)
391  CALL xt_idxlist_delete(src_idxlist)
392  CALL xt_idxlist_delete(dst_com(1:num_dst_intersections)%list)
393  CALL xt_idxlist_delete(src_com(1:num_src_intersections)%list)
394  END SUBROUTINE dedup_test
395 
396  SUBROUTINE test_xmap_iter(iter, msgs)
397  TYPE(xt_xmap_iter), INTENT(inout) :: iter
398  TYPE(test_message), INTENT(in) :: msgs(:)
399 
400  INTEGER :: num_msgs, num_pos, i, j
401  INTEGER, POINTER :: pos(:)
402  LOGICAL :: iter_is_null
403 
404  num_msgs = SIZE(msgs)
405  iter_is_null = xt_is_null(iter)
406  IF (num_msgs == 0) THEN
407  IF (.NOT. iter_is_null) &
408  CALL test_abort('ERROR: xt_xmap_get_*_iterator (non-null when ' &
409  // 'iter should be null)', &
410  __file__, &
411  __line__)
412  ELSE IF (iter_is_null) THEN
413  CALL test_abort('ERROR: xt_xmap_get_*_iterator ' &
414  // '(iter should not be NULL)', &
415  __file__, &
416  __line__)
417  ELSE
418  i = 1
419  DO WHILE(.true.)
420  IF (xt_xmap_iterator_get_rank(iter) /= msgs(i)%rank) &
421  CALL test_abort('ERROR: xt_xmap_iterator_get_rank', &
422  __file__, &
423  __line__)
424  num_pos = SIZE(msgs(i)%pos)
425  IF (xt_xmap_iterator_get_num_transfer_pos(iter) /= num_pos) THEN
426  CALL test_abort("ERROR: xt_xmap_iterator_get_num_transfer_pos", &
427  __file__, &
428  __line__)
429  END IF
431  DO j = 1, num_pos
432  IF (pos(j) /= msgs(i)%pos(j)) &
433  CALL test_abort('ERROR: xt_xmap_iterator_get_transfer_pos', &
434  __file__, &
435  __line__)
436  END DO
437  IF (.NOT. xt_xmap_iterator_next(iter)) EXIT
438  i = i + 1
439  END DO
440  IF (i /= num_msgs) &
441  CALL test_abort('ERROR: xt_xmap_iterator_next &
442  &(wrong number of messages)', &
443  __file__, &
444  __line__)
445  END IF
446  END SUBROUTINE test_xmap_iter
447 
448  SUBROUTINE test_xmap(xmap, send_messages, recv_messages)
449  TYPE(xt_xmap), INTENT(in) :: xmap
450  TYPE(test_message), INTENT(in) :: send_messages(:), recv_messages(:)
451 
452  INTEGER :: num_sends, num_recvs
453  TYPE(xt_xmap_iter) :: send_iter, recv_iter
454  INTEGER, PARAMETER :: num_xmaps_2_test = 2
455  INTEGER :: i
456  TYPE(xt_xmap) :: maps(num_xmaps_2_test)
457 
458  maps(1) = xmap
459  maps(2) = xt_xmap_copy(xmap)
460  DO i = 1, num_xmaps_2_test
461  num_sends = SIZE(send_messages)
462  num_recvs = SIZE(recv_messages)
463  IF (xt_xmap_get_num_destinations(maps(i)) /= num_sends) &
464  CALL test_abort('ERROR: xt_xmap_get_num_destinations', &
465  __file__, &
466  __line__)
467  IF (xt_xmap_get_num_sources(maps(i)) /= num_recvs) &
468  CALL test_abort('ERROR: xt_xmap_get_num_sources', &
469  __file__, &
470  __line__)
471  send_iter = xt_xmap_get_out_iterator(maps(i))
472  recv_iter = xt_xmap_get_in_iterator(maps(i))
473 
474  CALL test_xmap_iter(send_iter, send_messages)
475  CALL test_xmap_iter(recv_iter, recv_messages)
476 
477  IF (.NOT. xt_is_null(recv_iter)) CALL xt_xmap_iterator_delete(recv_iter)
478  IF (.NOT. xt_is_null(send_iter)) CALL xt_xmap_iterator_delete(send_iter)
479  END DO
480  CALL xt_xmap_delete(maps(2))
481  END SUBROUTINE test_xmap
482 
483  SUBROUTINE parse_options
484  INTEGER :: i, num_cmd_args, arg_len
485  INTEGER, PARAMETER :: max_opt_arg_len = 80
486  CHARACTER(max_opt_arg_len) :: optarg
487  num_cmd_args = command_argument_count()
488  i = 1
489  DO WHILE (i < num_cmd_args)
490  CALL get_command_argument(i, optarg, arg_len)
491  IF (optarg(1:2) == '-m' .AND. i < num_cmd_args .AND. arg_len == 2) THEN
492  CALL get_command_argument(i + 1, optarg, arg_len)
493  IF (arg_len > max_opt_arg_len) &
494  CALL test_abort('incorrect argument to command-line option -m', &
495  __file__, &
496  __line__)
497  IF (optarg(1:arg_len) == "xt_xmap_intersection_new") THEN
498  xmi_type = xmi_type_base
499  ELSE IF (optarg(1:arg_len) == "xt_xmap_intersection_ext_new") THEN
500  xmi_type = xmi_type_ext
501  ELSE
502  WRITE (0, *) 'arg to -m: ', optarg(1:arg_len)
503  CALL test_abort('incorrect argument to command-line option -m', &
504  __file__, &
505  __line__)
506  END IF
507  i = i + 2
508  ELSE
509  WRITE (0, *) 'unexpected command-line argument parsing error: ', &
510  trim(optarg)
511  FLUSH(0)
512  CALL test_abort('unexpected command-line argument -m', &
513  __file__, &
514  __line__)
515  END IF
516  END DO
517  END SUBROUTINE parse_options
518 
519  FUNCTION xmi_new(src_com, dst_com, src_idxlist, dst_idxlist, comm) &
520  result(xmap)
521  TYPE(xt_com_list), INTENT(in) :: src_com(:), dst_com(:)
522  TYPE(xt_idxlist), INTENT(in) :: src_idxlist, dst_idxlist
523  INTEGER, INTENT(in) :: comm
524  TYPE(xt_xmap) :: xmap
525  SELECT CASE(xmi_type)
526  CASE(xmi_type_base)
527  xmap = xt_xmap_intersection_new(src_com, dst_com, &
528  src_idxlist, dst_idxlist, comm)
529  CASE(xmi_type_ext)
530  xmap = xt_xmap_intersection_ext_new(src_com, dst_com, &
531  src_idxlist, dst_idxlist, comm)
532  END SELECT
533  END FUNCTION xmi_new
534 
535 END PROGRAM test_xmap_intersection_parallel
536 !
537 ! Local Variables:
538 ! f90-continuation-indent: 5
539 ! coding: utf-8
540 ! indent-tabs-mode: nil
541 ! show-trailing-whitespace: t
542 ! require-trailing-newline: t
543 ! End:
544 !