358 COMPLEX(kind=dp),
DIMENSION(:, :),
INTENT(out) :: target_m
359 INTEGER,
INTENT(in),
OPTIONAL :: start_row, start_col, n_rows, n_cols
360 LOGICAL,
INTENT(in),
OPTIONAL :: transpose
362 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_cfm_get_submatrix'
364 COMPLEX(kind=dp),
DIMENSION(:, :),
POINTER :: local_data
365 INTEGER :: end_col_global, end_col_local, end_row_global, end_row_local, handle, i, j, &
366 ncol_global, ncol_local, nrow_global, nrow_local, start_col_global, start_col_local, &
367 start_row_global, start_row_local, this_col
368 INTEGER,
DIMENSION(:),
POINTER :: col_indices, row_indices
369 LOGICAL :: do_zero, tr_a
372 CALL timeset(routinen, handle)
374 IF (
SIZE(target_m) /= 0)
THEN
375#if defined(__parallel)
382 IF (
PRESENT(transpose)) tr_a = transpose
387 IF (
PRESENT(start_row)) start_row_global = start_row
388 IF (
PRESENT(start_col)) start_col_global = start_col
391 end_row_global =
SIZE(target_m, 2)
392 end_col_global =
SIZE(target_m, 1)
394 end_row_global =
SIZE(target_m, 1)
395 end_col_global =
SIZE(target_m, 2)
397 IF (
PRESENT(n_rows)) end_row_global = n_rows
398 IF (
PRESENT(n_cols)) end_col_global = n_cols
400 end_row_global = end_row_global + start_row_global - 1
401 end_col_global = end_col_global + start_col_global - 1
404 nrow_global=nrow_global, ncol_global=ncol_global, &
405 nrow_local=nrow_local, ncol_local=ncol_local, &
406 row_indices=row_indices, col_indices=col_indices)
407 IF (end_row_global > nrow_global)
THEN
408 end_row_global = nrow_global
411 IF (end_col_global > ncol_global)
THEN
412 end_col_global = ncol_global
418 DO start_row_local = 1, nrow_local
419 IF (row_indices(start_row_local) >= start_row_global)
EXIT
422 DO end_row_local = start_row_local, nrow_local
423 IF (row_indices(end_row_local) > end_row_global)
EXIT
425 end_row_local = end_row_local - 1
427 DO start_col_local = 1, ncol_local
428 IF (col_indices(start_col_local) >= start_col_global)
EXIT
431 DO end_col_local = start_col_local, ncol_local
432 IF (col_indices(end_col_local) > end_col_global)
EXIT
434 end_col_local = end_col_local - 1
436 para_env => fm%matrix_struct%para_env
437 local_data => fm%local_data
444 CALL zcopy(
SIZE(target_m),
z_zero, 0, target_m(1, 1), 1)
448 DO j = start_col_local, end_col_local
449 this_col = col_indices(j) - start_col_global + 1
450 DO i = start_row_local, end_row_local
451 target_m(this_col, row_indices(i) - start_row_global + 1) = local_data(i, j)
455 DO j = start_col_local, end_col_local
456 this_col = col_indices(j) - start_col_global + 1
457 DO i = start_row_local, end_row_local
458 target_m(row_indices(i) - start_row_global + 1, this_col) = local_data(i, j)
463 CALL para_env%sum(target_m)
466 CALL timestop(handle)
494 start_col, n_rows, n_cols, alpha, beta, transpose)
496 COMPLEX(kind=dp),
DIMENSION(:, :),
INTENT(in) :: new_values
497 INTEGER,
INTENT(in),
OPTIONAL :: start_row, start_col, n_rows, n_cols
498 COMPLEX(kind=dp),
INTENT(in),
OPTIONAL :: alpha, beta
499 LOGICAL,
INTENT(in),
OPTIONAL :: transpose
501 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_cfm_set_submatrix'
503 COMPLEX(kind=dp) :: al, be
504 COMPLEX(kind=dp),
DIMENSION(:, :),
POINTER :: local_data
505 INTEGER :: end_col_global, end_col_local, end_row_global, end_row_local, handle, i, j, &
506 ncol_global, ncol_local, nrow_global, nrow_local, start_col_global, start_col_local, &
507 start_row_global, start_row_local, this_col
508 INTEGER,
DIMENSION(:),
POINTER :: col_indices, row_indices
511 CALL timeset(routinen, handle)
515 IF (
PRESENT(alpha)) al = alpha
516 IF (
PRESENT(beta)) be = beta
521 IF (
PRESENT(start_row)) start_row_global = start_row
522 IF (
PRESENT(start_col)) start_col_global = start_col
525 IF (
PRESENT(transpose)) tr_a = transpose
528 end_row_global =
SIZE(new_values, 2)
529 end_col_global =
SIZE(new_values, 1)
531 end_row_global =
SIZE(new_values, 1)
532 end_col_global =
SIZE(new_values, 2)
534 IF (
PRESENT(n_rows)) end_row_global = n_rows
535 IF (
PRESENT(n_cols)) end_col_global = n_cols
537 end_row_global = end_row_global + start_row_global - 1
538 end_col_global = end_col_global + start_col_global - 1
541 nrow_global=nrow_global, ncol_global=ncol_global, &
542 nrow_local=nrow_local, ncol_local=ncol_local, &
543 row_indices=row_indices, col_indices=col_indices)
544 IF (end_row_global > nrow_global) end_row_global = nrow_global
545 IF (end_col_global > ncol_global) end_col_global = ncol_global
549 DO start_row_local = 1, nrow_local
550 IF (row_indices(start_row_local) >= start_row_global)
EXIT
553 DO end_row_local = start_row_local, nrow_local
554 IF (row_indices(end_row_local) > end_row_global)
EXIT
556 end_row_local = end_row_local - 1
558 DO start_col_local = 1, ncol_local
559 IF (col_indices(start_col_local) >= start_col_global)
EXIT
562 DO end_col_local = start_col_local, ncol_local
563 IF (col_indices(end_col_local) > end_col_global)
EXIT
565 end_col_local = end_col_local - 1
567 local_data => matrix%local_data
571 DO j = start_col_local, end_col_local
572 this_col = col_indices(j) - start_col_global + 1
573 DO i = start_row_local, end_row_local
574 local_data(i, j) = new_values(this_col, row_indices(i) - start_row_global + 1)
578 DO j = start_col_local, end_col_local
579 this_col = col_indices(j) - start_col_global + 1
580 DO i = start_row_local, end_row_local
581 local_data(i, j) = new_values(row_indices(i) - start_row_global + 1, this_col)
587 DO j = start_col_local, end_col_local
588 this_col = col_indices(j) - start_col_global + 1
589 DO i = start_row_local, end_row_local
590 local_data(i, j) = al*new_values(this_col, row_indices(i) - start_row_global + 1) + &
595 DO j = start_col_local, end_col_local
596 this_col = col_indices(j) - start_col_global + 1
597 DO i = start_row_local, end_row_local
598 local_data(i, j) = al*new_values(row_indices(i) - start_row_global + 1, this_col) + &
605 CALL timestop(handle)
937 TYPE(
cp_cfm_type),
INTENT(IN) :: source, destination
941 CHARACTER(len=*),
PARAMETER :: routinen =
'cp_cfm_start_copy_general'
943 INTEGER :: dest_p_i, dest_q_j, global_rank, global_size, handle, i, j, k, mpi_rank, &
944 ncol_block_dest, ncol_block_src, ncol_local_recv, ncol_local_send, ncols, &
945 nrow_block_dest, nrow_block_src, nrow_local_recv, nrow_local_send, nrows, p, q, &
946 recv_rank, recv_size, send_rank, send_size
947 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: all_ranks, dest2global, dest_p, dest_q, &
948 recv_count, send_count, send_disp, &
949 source2global, src_p, src_q
950 INTEGER,
ALLOCATABLE,
DIMENSION(:, :) :: dest_blacs2mpi
951 INTEGER,
DIMENSION(2) :: dest_block, dest_block_tmp, dest_num_pe, &
952 src_block, src_block_tmp, src_num_pe
953 INTEGER,
DIMENSION(:),
POINTER :: recv_col_indices, recv_row_indices, &
954 send_col_indices, send_row_indices
958 CALL timeset(routinen, handle)
962 nrow_local_send =
SIZE(source%local_data, 1)
963 ncol_local_send =
SIZE(source%local_data, 2)
964 ALLOCATE (info%send_buf(nrow_local_send*ncol_local_send))
966 DO j = 1, ncol_local_send
967 DO i = 1, nrow_local_send
969 info%send_buf(k) = source%local_data(i, j)
973 NULLIFY (recv_dist, send_dist)
974 NULLIFY (recv_col_indices, recv_row_indices, send_col_indices, send_row_indices)
977 global_size = para_env%num_pe
978 global_rank = para_env%mepos
984 IF (
ASSOCIATED(destination%matrix_struct))
THEN
985 recv_dist => destination%matrix_struct
986 recv_rank = recv_dist%para_env%mepos
991 IF (
ASSOCIATED(source%matrix_struct))
THEN
992 send_dist => source%matrix_struct
993 send_rank = send_dist%para_env%mepos
999 ALLOCATE (all_ranks(0:global_size - 1))
1001 CALL para_env%allgather(send_rank, all_ranks)
1002 IF (
ASSOCIATED(destination%matrix_struct))
THEN
1003 ALLOCATE (source2global(0:count(all_ranks /=
mp_proc_null) - 1))
1004 DO i = 0, global_size - 1
1006 source2global(all_ranks(i)) = i
1011 CALL para_env%allgather(recv_rank, all_ranks)
1012 IF (
ASSOCIATED(source%matrix_struct))
THEN
1013 ALLOCATE (dest2global(0:count(all_ranks /=
mp_proc_null) - 1))
1014 DO i = 0, global_size - 1
1016 dest2global(all_ranks(i)) = i
1020 DEALLOCATE (all_ranks)
1027 IF (global_rank == 0)
THEN
1029 CALL para_env%irecv(src_block,
mp_any_source, recv_req(1), tag=src_tag)
1030 CALL para_env%irecv(dest_block,
mp_any_source, recv_req(2), tag=dest_tag)
1031 CALL para_env%irecv(src_num_pe,
mp_any_source, recv_req(3), tag=src_tag)
1032 CALL para_env%irecv(dest_num_pe,
mp_any_source, recv_req(4), tag=dest_tag)
1035 IF (
ASSOCIATED(source%matrix_struct))
THEN
1036 IF ((send_rank == 0))
THEN
1038 src_block_tmp = [send_dist%nrow_block, send_dist%ncol_block]
1039 CALL para_env%isend(src_block_tmp, 0, send_req(1), tag=src_tag)
1040 CALL para_env%isend(send_dist%context%num_pe, 0, send_req(2), tag=src_tag)
1044 IF (
ASSOCIATED(destination%matrix_struct))
THEN
1045 IF ((recv_rank == 0))
THEN
1046 dest_block_tmp = [recv_dist%nrow_block, recv_dist%ncol_block]
1047 CALL para_env%isend(dest_block_tmp, 0, send_req(3), tag=dest_tag)
1048 CALL para_env%isend(recv_dist%context%num_pe, 0, send_req(4), tag=dest_tag)
1052 IF (global_rank == 0)
THEN
1055 ALLOCATE (info%src_blacs2mpi(0:src_num_pe(1) - 1, 0:src_num_pe(2) - 1), &
1056 dest_blacs2mpi(0:dest_num_pe(1) - 1, 0:dest_num_pe(2) - 1))
1057 CALL para_env%irecv(info%src_blacs2mpi,
mp_any_source, recv_req(5), tag=src_tag)
1058 CALL para_env%irecv(dest_blacs2mpi,
mp_any_source, recv_req(6), tag=dest_tag)
1061 IF (
ASSOCIATED(source%matrix_struct))
THEN
1062 IF ((send_rank == 0))
THEN
1063 CALL para_env%isend(send_dist%context%blacs2mpi(:, :), 0, send_req(5), tag=src_tag)
1067 IF (
ASSOCIATED(destination%matrix_struct))
THEN
1068 IF ((recv_rank == 0))
THEN
1069 CALL para_env%isend(recv_dist%context%blacs2mpi(:, :), 0, send_req(6), tag=dest_tag)
1073 IF (global_rank == 0)
THEN
1078 CALL para_env%bcast(src_block, 0)
1079 CALL para_env%bcast(dest_block, 0)
1080 CALL para_env%bcast(src_num_pe, 0)
1081 CALL para_env%bcast(dest_num_pe, 0)
1082 info%src_num_pe(1:2) = src_num_pe(1:2)
1083 info%nblock_src(1:2) = src_block(1:2)
1084 IF (global_rank /= 0)
THEN
1085 ALLOCATE (info%src_blacs2mpi(0:src_num_pe(1) - 1, 0:src_num_pe(2) - 1), &
1086 dest_blacs2mpi(0:dest_num_pe(1) - 1, 0:dest_num_pe(2) - 1))
1088 CALL para_env%bcast(info%src_blacs2mpi, 0)
1089 CALL para_env%bcast(dest_blacs2mpi, 0)
1091 recv_size = dest_num_pe(1)*dest_num_pe(2)
1092 send_size = src_num_pe(1)*src_num_pe(2)
1093 info%send_size = send_size
1112 IF (
ASSOCIATED(destination%matrix_struct))
THEN
1114 col_indices=recv_col_indices)
1115 info%recv_col_indices => recv_col_indices
1116 info%recv_row_indices => recv_row_indices
1117 nrow_block_src = src_block(1)
1118 ncol_block_src = src_block(2)
1119 ALLOCATE (recv_count(0:send_size - 1), info%recv_disp(0:send_size - 1), info%recv_request(0:send_size - 1))
1122 nrow_local_recv = recv_dist%nrow_locals(recv_dist%context%mepos(1))
1123 ncol_local_recv = recv_dist%ncol_locals(recv_dist%context%mepos(2))
1124 info%nlocal_recv(1) = nrow_local_recv
1125 info%nlocal_recv(2) = ncol_local_recv
1127 ALLOCATE (src_p(nrow_local_recv), src_q(ncol_local_recv))
1128 DO i = 1, nrow_local_recv
1131 src_p(i) = mod(((recv_row_indices(i) - 1)/nrow_block_src), src_num_pe(1))
1133 DO j = 1, ncol_local_recv
1135 src_q(j) = mod(((recv_col_indices(j) - 1)/ncol_block_src), src_num_pe(2))
1139 DO q = 0, src_num_pe(2) - 1
1140 ncols = count(src_q == q)
1141 DO p = 0, src_num_pe(1) - 1
1142 nrows = count(src_p == p)
1144 recv_count(info%src_blacs2mpi(p, q)) = nrows*ncols
1147 DEALLOCATE (src_p, src_q)
1151 ALLOCATE (info%recv_buf(sum(recv_count(:))))
1152 info%recv_disp(0) = 0
1153 DO i = 1, send_size - 1
1154 info%recv_disp(i) = info%recv_disp(i - 1) + recv_count(i - 1)
1158 DO k = 0, send_size - 1
1159 IF (recv_count(k) > 0)
THEN
1160 CALL para_env%irecv(info%recv_buf(info%recv_disp(k) + 1:info%recv_disp(k) + recv_count(k)), &
1161 source2global(k), info%recv_request(k))
1166 DEALLOCATE (source2global)
1170 IF (
ASSOCIATED(source%matrix_struct))
THEN
1172 col_indices=send_col_indices)
1173 nrow_block_dest = dest_block(1)
1174 ncol_block_dest = dest_block(2)
1175 ALLOCATE (send_count(0:recv_size - 1), send_disp(0:recv_size - 1), info%send_request(0:recv_size - 1))
1178 nrow_local_send = send_dist%nrow_locals(send_dist%context%mepos(1))
1179 ncol_local_send = send_dist%ncol_locals(send_dist%context%mepos(2))
1183 ALLOCATE (dest_p(nrow_local_send), dest_q(ncol_local_send))
1185 DO i = 1, nrow_local_send
1187 dest_p(i) = mod(((send_row_indices(i) - 1)/nrow_block_dest), dest_num_pe(1))
1189 DO j = 1, ncol_local_send
1190 dest_q(j) = mod(((send_col_indices(j) - 1)/ncol_block_dest), dest_num_pe(2))
1194 DO q = 0, dest_num_pe(2) - 1
1195 ncols = count(dest_q == q)
1196 DO p = 0, dest_num_pe(1) - 1
1197 nrows = count(dest_p == p)
1198 send_count(dest_blacs2mpi(p, q)) = nrows*ncols
1201 DEALLOCATE (dest_p, dest_q)
1204 ALLOCATE (info%send_buf(sum(send_count(:))))
1206 DO k = 1, recv_size - 1
1207 send_disp(k) = send_disp(k - 1) + send_count(k - 1)
1212 DO j = 1, ncol_local_send
1214 dest_q_j = mod(((send_col_indices(j) - 1)/ncol_block_dest), dest_num_pe(2))
1215 DO i = 1, nrow_local_send
1216 dest_p_i = mod(((send_row_indices(i) - 1)/nrow_block_dest), dest_num_pe(1))
1217 mpi_rank = dest_blacs2mpi(dest_p_i, dest_q_j)
1218 send_count(mpi_rank) = send_count(mpi_rank) + 1
1219 info%send_buf(send_disp(mpi_rank) + send_count(mpi_rank)) = source%local_data(i, j)
1224 DO k = 0, recv_size - 1
1225 IF (send_count(k) > 0)
THEN
1226 CALL para_env%isend(info%send_buf(send_disp(k) + 1:send_disp(k) + send_count(k)), &
1227 dest2global(k), info%send_request(k))
1232 DEALLOCATE (send_count, send_disp, dest2global)
1234 DEALLOCATE (dest_blacs2mpi)
1238 CALL timestop(handle)