45 PROGRAM test_xmap_intersection_parallel
46 USE ftest_common
, ONLY: init_mpi, finish_mpi, test_abort
48 USE test_idxlist_utils
, ONLY: test_err_count
59 #if defined __PGI && ( __PGIC__ < 12 || (__PGIC__ == 12 && __PGIC_MINOR__ <= 7)) 64 USE yaxt, ONLY: xt_is_null
70 INTEGER,
POINTER :: pos(:)
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
79 INTEGER,
PARAMETER :: xmi_type_base = 0, xmi_type_ext = 1
83 INTEGER :: my_rank, comm_size
87 xmi_type = xmi_type_base
90 CALL mpi_comm_rank(mpi_comm_world, my_rank, ierror)
91 IF (ierror /= mpi_success) &
92 CALL test_abort(
"MPI error!", &
96 CALL mpi_comm_size(mpi_comm_world, comm_size, ierror)
97 IF (ierror /= mpi_success) &
98 CALL test_abort(
"MPI error!", &
102 IF (comm_size /= 3)
THEN 110 CALL elimination_test
111 CALL one_to_one_comm_test
112 CALL full_comm_matrix_test
115 IF (test_err_count() /= 0) &
116 CALL test_abort(
"non-zero error count!", &
124 SUBROUTINE simple_rr_test
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)
135 TYPE(test_message) :: send_messages(1), recv_messages(1)
137 src_index(1) = int(my_rank, xi)
138 dst_index(1) = int(mod(my_rank + 1, comm_size), xi)
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))
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)
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
154 CALL test_xmap(xmap, send_messages, recv_messages)
160 END SUBROUTINE simple_rr_test
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, &
169 INTEGER,
TARGET :: send_pos(1), recv_pos(1)
170 TYPE(xt_com_list) :: src_com(1), dst_com(2)
172 TYPE(test_message) :: send_messages(1), recv_messages(1)
174 IF (my_rank == 0)
THEN 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)
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)
193 num_sends = merge(1, 0, my_rank == 1)
194 send_messages(1)%rank = 0
195 send_messages(1)%pos => send_pos
197 num_recvs = merge(1, 0, my_rank == 0)
198 recv_messages(1)%rank = 1
199 recv_messages(1)%pos => recv_pos
201 CALL test_xmap(xmap, send_messages(1:num_sends), recv_messages(1:num_recvs))
208 END SUBROUTINE elimination_test
211 SUBROUTINE one_to_one_comm_test
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)
223 TYPE(test_message) :: send_messages(2), recv_messages(1)
225 dst_index(1) = int(my_rank, xi)
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)
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, &
244 SELECT CASE (my_rank)
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
257 send_messages(1)%rank = 0
258 send_messages(1)%pos => send_pos(1:1)
259 recv_messages(1)%rank = 0
262 recv_messages(1)%rank = 0
264 recv_messages(1)%pos => recv_pos(1:1)
265 CALL test_xmap(xmap, send_messages(1:num_sends), recv_messages(1:num_recvs))
273 END SUBROUTINE one_to_one_comm_test
276 SUBROUTINE full_comm_matrix_test
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 /)), &
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)
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 /), &
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)
304 src_com(i) = xt_com_list(src_idxlist, i)
305 dst_com(i) = xt_com_list(
xt_idxvec_new(src_indices(:, i)), i)
307 xmap = xmi_new(src_com, dst_com, src_idxlist, dst_idxlist, &
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)
317 CALL test_xmap(xmap, send_messages, recv_messages)
326 END SUBROUTINE full_comm_matrix_test
330 SUBROUTINE dedup_test
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 /)
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)
350 IF (my_rank == 2)
THEN 351 num_src_intersections = 0
352 num_dst_intersections = 2
355 dst_com(i+1)%rank = i
360 num_src_intersections = 1
363 num_dst_intersections = 0;
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)
372 IF (my_rank == 2)
THEN 373 num_recv_messages = 2
374 num_send_messages = 0
376 recv_messages(i)%rank = i - 1
377 recv_messages(i)%pos => recv_pos(1:num_recv_pos(i), i)
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)
385 CALL test_xmap(xmap, send_messages(1:num_send_messages), &
386 recv_messages(1:num_recv_messages))
394 END SUBROUTINE dedup_test
396 SUBROUTINE test_xmap_iter(iter, msgs)
398 TYPE(test_message),
INTENT(in) :: msgs(:)
400 INTEGER :: num_msgs, num_pos, i, j
401 INTEGER,
POINTER :: pos(:)
402 LOGICAL :: iter_is_null
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)', &
412 ELSE IF (iter_is_null)
THEN 413 CALL test_abort(
'ERROR: xt_xmap_get_*_iterator ' &
414 //
'(iter should not be NULL)', &
421 CALL test_abort(
'ERROR: xt_xmap_iterator_get_rank', &
424 num_pos =
SIZE(msgs(i)%pos)
426 CALL test_abort(
"ERROR: xt_xmap_iterator_get_num_transfer_pos", &
432 IF (pos(j) /= msgs(i)%pos(j)) &
433 CALL test_abort(
'ERROR: xt_xmap_iterator_get_transfer_pos', &
441 CALL test_abort(
'ERROR: xt_xmap_iterator_next & 442 &(wrong number of messages)', &
446 END SUBROUTINE test_xmap_iter
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(:)
452 INTEGER :: num_sends, num_recvs
454 INTEGER,
PARAMETER :: num_xmaps_2_test = 2
456 TYPE(
xt_xmap) :: maps(num_xmaps_2_test)
460 DO i = 1, num_xmaps_2_test
461 num_sends =
SIZE(send_messages)
462 num_recvs =
SIZE(recv_messages)
464 CALL test_abort(
'ERROR: xt_xmap_get_num_destinations', &
468 CALL test_abort(
'ERROR: xt_xmap_get_num_sources', &
474 CALL test_xmap_iter(send_iter, send_messages)
475 CALL test_xmap_iter(recv_iter, recv_messages)
481 END SUBROUTINE test_xmap
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()
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', &
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
502 WRITE (0, *)
'arg to -m: ', optarg(1:arg_len)
503 CALL test_abort(
'incorrect argument to command-line option -m', &
509 WRITE (0, *)
'unexpected command-line argument parsing error: ', &
512 CALL test_abort(
'unexpected command-line argument -m', &
517 END SUBROUTINE parse_options
519 FUNCTION xmi_new(src_com, dst_com, src_idxlist, dst_idxlist, comm) &
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
525 SELECT CASE(xmi_type)
528 src_idxlist, dst_idxlist, comm)
531 src_idxlist, dst_idxlist, comm)
535 END PROGRAM test_xmap_intersection_parallel