455 INTEGER,
INTENT(IN),
OPTIONAL :: ncol, start_col
457 CHARACTER(LEN=*),
PARAMETER :: routinen =
'cp_fm_init_random'
459 INTEGER :: handle, icol_global, icol_local, irow_local, my_ncol, my_start_col, ncol_global, &
460 ncol_local, nrow_global, nrow_local
461 INTEGER,
DIMENSION(:),
POINTER :: col_indices, row_indices
462 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: buff
463 REAL(kind=
dp),
CONTIGUOUS,
DIMENSION(:, :), &
464 POINTER :: local_data
465 REAL(kind=
dp),
DIMENSION(3, 2),
SAVE :: &
466 seed = reshape([1.0_dp, 2.0_dp, 3.0_dp, 4.0_dp, 5.0_dp, 6.0_dp], [3, 2])
469 CALL timeset(routinen, handle)
472 CALL matrix%matrix_struct%para_env%bcast(seed, 0)
475 extended_precision=.true., seed=seed)
477 CALL cp_fm_get_info(matrix, nrow_global=nrow_global, ncol_global=ncol_global, &
478 nrow_local=nrow_local, ncol_local=ncol_local, &
479 local_data=local_data, &
480 row_indices=row_indices, col_indices=col_indices)
483 IF (
PRESENT(start_col)) my_start_col = start_col
484 my_ncol = matrix%matrix_struct%ncol_global
485 IF (
PRESENT(ncol)) my_ncol = ncol
487 IF (ncol_global < (my_start_col + my_ncol - 1))
THEN
488 cpabort(
"ncol_global>=(my_start_col+my_ncol-1)")
491 ALLOCATE (buff(nrow_global))
497 DO icol_local = 1, ncol_local
498 cpassert(col_indices(icol_local) > icol_global)
500 CALL rng%reset_to_next_substream()
501 icol_global = icol_global + 1
502 IF (icol_global == col_indices(icol_local))
EXIT
505 DO irow_local = 1, nrow_local
506 local_data(irow_local, icol_local) = buff(row_indices(irow_local))
519 CALL rng%get(ig=seed)
521 CALL timestop(handle)
569 REAL(kind=
dp),
DIMENSION(:),
INTENT(OUT) :: diag
570 INTEGER,
INTENT(IN),
OPTIONAL :: n_active
572 INTEGER :: i_global, n_diag, ncol_global, nrow_global
573#if defined(__parallel)
574 INTEGER :: icol_local, ipcol, iprow, irow, irow_local, &
575 mypcol, myprow, npcol, nprow, nrow_local
576 INTEGER,
DIMENSION(9) :: desca
577 INTEGER,
DIMENSION(:),
POINTER :: row_indices
581 CALL cp_fm_get_info(matrix, nrow_global=nrow_global, ncol_global=ncol_global)
583 n_diag = min(nrow_global, ncol_global)
584 IF (
PRESENT(n_active)) n_diag = n_active
585 cpassert(n_diag >= 0 .AND. n_diag <= min(nrow_global, ncol_global))
586 cpassert(
SIZE(diag) >= n_diag)
589#if defined(__parallel)
590 CALL cp_fm_get_info(matrix, nrow_local=nrow_local, row_indices=row_indices)
591 context => matrix%matrix_struct%context
592 myprow = context%mepos(1)
593 mypcol = context%mepos(2)
594 nprow = context%num_pe(1)
595 npcol = context%num_pe(2)
597 desca(:) = matrix%matrix_struct%descriptor(:)
599 DO irow = 1, nrow_local
600 i_global = row_indices(irow)
601 IF (i_global > n_diag)
EXIT
602 CALL infog2l(i_global, i_global, desca, nprow, npcol, myprow, mypcol, &
603 irow_local, icol_local, iprow, ipcol)
604 IF ((iprow == myprow) .AND. (ipcol == mypcol))
THEN
605 diag(i_global) = matrix%local_data(irow_local, icol_local)
609 DO i_global = 1, n_diag
610 diag(i_global) = matrix%local_data(i_global, i_global)
613 CALL matrix%matrix_struct%para_env%sum(diag)
757 start_col, n_rows, n_cols, alpha, beta, transpose)
759 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(in) :: new_values
760 INTEGER,
INTENT(in),
OPTIONAL :: start_row, start_col, n_rows, n_cols
761 REAL(kind=
dp),
INTENT(in),
OPTIONAL :: alpha, beta
762 LOGICAL,
INTENT(in),
OPTIONAL :: transpose
764 INTEGER :: i, i0, j, j0, ncol, ncol_block, &
765 ncol_global, ncol_local, nrow, &
766 nrow_block, nrow_global, nrow_local, &
768 INTEGER,
DIMENSION(:),
POINTER :: col_indices, row_indices
770 REAL(kind=
dp) :: al, be
771 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: full_block
773 al = 1.0_dp; be = 0.0_dp; i0 = 1; j0 = 1; tr_a = .false.
775 IF (
PRESENT(alpha)) al = alpha
776 IF (
PRESENT(beta)) be = beta
777 IF (
PRESENT(start_row)) i0 = start_row
778 IF (
PRESENT(start_col)) j0 = start_col
779 IF (
PRESENT(transpose)) tr_a = transpose
781 nrow =
SIZE(new_values, 2)
782 ncol =
SIZE(new_values, 1)
784 nrow =
SIZE(new_values, 1)
785 ncol =
SIZE(new_values, 2)
787 IF (
PRESENT(n_rows)) nrow = n_rows
788 IF (
PRESENT(n_cols)) ncol = n_cols
790 full_block => fm%local_data
793 nrow_global=nrow_global, ncol_global=ncol_global, &
794 nrow_block=nrow_block, ncol_block=ncol_block, &
795 nrow_local=nrow_local, ncol_local=ncol_local, &
796 row_indices=row_indices, col_indices=col_indices)
798 IF (al == 1.0_dp .AND. be == 0.0_dp)
THEN
800 this_col = col_indices(j) - j0 + 1
801 IF (this_col >= 1 .AND. this_col <= ncol)
THEN
803 IF (i0 == 1 .AND. nrow_global == nrow)
THEN
805 full_block(i, j) = new_values(this_col, row_indices(i))
809 this_row = row_indices(i) - i0 + 1
810 IF (this_row >= 1 .AND. this_row <= nrow)
THEN
811 full_block(i, j) = new_values(this_col, this_row)
816 IF (i0 == 1 .AND. nrow_global == nrow)
THEN
818 full_block(i, j) = new_values(row_indices(i), this_col)
822 this_row = row_indices(i) - i0 + 1
823 IF (this_row >= 1 .AND. this_row <= nrow)
THEN
824 full_block(i, j) = new_values(this_row, this_col)
833 this_col = col_indices(j) - j0 + 1
834 IF (this_col >= 1 .AND. this_col <= ncol)
THEN
837 this_row = row_indices(i) - i0 + 1
838 IF (this_row >= 1 .AND. this_row <= nrow)
THEN
839 full_block(i, j) = al*new_values(this_col, this_row) + &
845 this_row = row_indices(i) - i0 + 1
846 IF (this_row >= 1 .AND. this_row <= nrow)
THEN
847 full_block(i, j) = al*new_values(this_row, this_col) + &
932 start_col, n_rows, n_cols, transpose)
934 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(out) :: target_m
935 INTEGER,
INTENT(in),
OPTIONAL :: start_row, start_col, n_rows, n_cols
936 LOGICAL,
INTENT(in),
OPTIONAL :: transpose
938 CHARACTER(LEN=*),
PARAMETER :: routinen =
'cp_fm_get_submatrix'
940 INTEGER :: handle, i, i0, j, j0, ncol, ncol_global, &
941 ncol_local, nrow, nrow_global, &
942 nrow_local, this_col, this_row
943 INTEGER,
DIMENSION(:),
POINTER :: col_indices, row_indices
945 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: full_block
948 CALL timeset(routinen, handle)
950 i0 = 1; j0 = 1; tr_a = .false.
952 IF (
PRESENT(start_row)) i0 = start_row
953 IF (
PRESENT(start_col)) j0 = start_col
954 IF (
PRESENT(transpose)) tr_a = transpose
956 nrow =
SIZE(target_m, 2)
957 ncol =
SIZE(target_m, 1)
959 nrow =
SIZE(target_m, 1)
960 ncol =
SIZE(target_m, 2)
962 IF (
PRESENT(n_rows)) nrow = n_rows
963 IF (
PRESENT(n_cols)) ncol = n_cols
965 para_env => fm%matrix_struct%para_env
967 full_block => fm%local_data
968#if defined(__parallel)
970 IF (
SIZE(target_m, 1)*
SIZE(target_m, 2) /= 0)
THEN
971 CALL dcopy(
SIZE(target_m, 1)*
SIZE(target_m, 2), [0.0_dp], 0, target_m, 1)
976 nrow_global=nrow_global, ncol_global=ncol_global, &
977 nrow_local=nrow_local, ncol_local=ncol_local, &
978 row_indices=row_indices, col_indices=col_indices)
981 this_col = col_indices(j) - j0 + 1
982 IF (this_col >= 1 .AND. this_col <= ncol)
THEN
984 IF (i0 == 1 .AND. nrow_global == nrow)
THEN
986 target_m(this_col, row_indices(i)) = full_block(i, j)
990 this_row = row_indices(i) - i0 + 1
991 IF (this_row >= 1 .AND. this_row <= nrow)
THEN
992 target_m(this_col, this_row) = full_block(i, j)
997 IF (i0 == 1 .AND. nrow_global == nrow)
THEN
999 target_m(row_indices(i), this_col) = full_block(i, j)
1002 DO i = 1, nrow_local
1003 this_row = row_indices(i) - i0 + 1
1004 IF (this_row >= 1 .AND. this_row <= nrow)
THEN
1005 target_m(this_row, this_col) = full_block(i, j)
1013 CALL para_env%sum(target_m)
1015 CALL timestop(handle)
1043 nrow_block, ncol_block, nrow_local, ncol_local, &
1044 row_indices, col_indices, local_data, context, &
1045 nrow_locals, ncol_locals, matrix_struct, para_env)
1048 CHARACTER(LEN=*),
INTENT(OUT),
OPTIONAL :: name
1049 INTEGER,
INTENT(OUT),
OPTIONAL :: nrow_global, ncol_global, nrow_block, &
1050 ncol_block, nrow_local, ncol_local
1051 INTEGER,
DIMENSION(:),
OPTIONAL,
POINTER :: row_indices, col_indices
1052 REAL(kind=
dp),
CONTIGUOUS,
DIMENSION(:, :), &
1053 OPTIONAL,
POINTER :: local_data
1055 INTEGER,
DIMENSION(:),
OPTIONAL,
POINTER :: nrow_locals, ncol_locals
1059 IF (
PRESENT(name)) name = matrix%name
1060 IF (
PRESENT(matrix_struct)) matrix_struct => matrix%matrix_struct
1061 IF (
PRESENT(local_data)) local_data => matrix%local_data
1064 ncol_local=ncol_local, nrow_global=nrow_global, &
1065 ncol_global=ncol_global, nrow_block=nrow_block, &
1066 ncol_block=ncol_block, row_indices=row_indices, &
1067 col_indices=col_indices, nrow_locals=nrow_locals, &
1068 ncol_locals=ncol_locals, context=context, para_env=para_env)
1095 REAL(kind=
dp),
INTENT(OUT) :: a_max
1096 INTEGER,
INTENT(OUT),
OPTIONAL :: ir_max, ic_max
1098 CHARACTER(LEN=*),
PARAMETER :: routinen =
'cp_fm_maxabsval'
1100 INTEGER :: handle, i, ic_max_local, ir_max_local, &
1101 j, mepos, ncol_local, nrow_local, &
1103 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: ic_max_vec, ir_max_vec
1104 INTEGER,
DIMENSION(:),
POINTER :: col_indices, row_indices
1106 REAL(
dp),
ALLOCATABLE,
DIMENSION(:) :: a_max_vec
1107 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: my_block
1109 CALL timeset(routinen, handle)
1111 my_block => matrix%local_data
1113 CALL cp_fm_get_info(matrix, nrow_local=nrow_local, ncol_local=ncol_local, &
1114 row_indices=row_indices, col_indices=col_indices)
1116 a_max = maxval(abs(my_block(1:nrow_local, 1:ncol_local)))
1118 IF (
PRESENT(ir_max))
THEN
1119 num_pe = matrix%matrix_struct%para_env%num_pe
1120 mepos = matrix%matrix_struct%para_env%mepos
1121 ALLOCATE (ir_max_vec(0:num_pe - 1))
1122 ir_max_vec(0:num_pe - 1) = 0
1123 ALLOCATE (ic_max_vec(0:num_pe - 1))
1124 ic_max_vec(0:num_pe - 1) = 0
1125 ALLOCATE (a_max_vec(0:num_pe - 1))
1126 a_max_vec(0:num_pe - 1) = 0.0_dp
1129 IF ((ncol_local > 0) .AND. (nrow_local > 0))
THEN
1130 DO i = 1, ncol_local
1131 DO j = 1, nrow_local
1132 IF (abs(my_block(j, i)) > my_max)
THEN
1133 my_max = my_block(j, i)
1140 a_max_vec(mepos) = my_max
1141 ir_max_vec(mepos) = row_indices(ir_max_local)
1142 ic_max_vec(mepos) = col_indices(ic_max_local)
1146 CALL matrix%matrix_struct%para_env%sum(a_max_vec)
1147 CALL matrix%matrix_struct%para_env%sum(ir_max_vec)
1148 CALL matrix%matrix_struct%para_env%sum(ic_max_vec)
1151 DO i = 0, num_pe - 1
1152 IF (a_max_vec(i) > my_max)
THEN
1153 ir_max = ir_max_vec(i)
1154 ic_max = ic_max_vec(i)
1158 DEALLOCATE (ir_max_vec, ic_max_vec, a_max_vec)
1159 cpassert(ic_max > 0)
1160 cpassert(ir_max > 0)
1164 CALL matrix%matrix_struct%para_env%max(a_max)
1166 CALL timestop(handle)
1617 TYPE(
cp_fm_type),
INTENT(IN) :: source, destination
1621 CHARACTER(LEN=*),
PARAMETER :: routinen =
'cp_fm_start_copy_general'
1623 INTEGER :: dest_p_i, dest_q_j, global_rank, global_size, handle, i, j, k, mpi_rank, &
1624 ncol_block_dest, ncol_block_src, ncol_local_recv, ncol_local_send, ncols, &
1625 nrow_block_dest, nrow_block_src, nrow_local_recv, nrow_local_send, nrows, p, q, &
1626 recv_rank, recv_size, send_rank, send_size
1627 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: all_ranks, dest2global, dest_p, dest_q, &
1628 recv_count, send_count, send_disp, &
1629 source2global, src_p, src_q
1630 INTEGER,
ALLOCATABLE,
DIMENSION(:, :) :: dest_blacs2mpi
1631 INTEGER,
DIMENSION(2) :: dest_block, dest_block_tmp, dest_num_pe, &
1632 src_block, src_block_tmp, src_num_pe
1633 INTEGER,
DIMENSION(:),
POINTER :: recv_col_indices, recv_row_indices, &
1634 send_col_indices, send_row_indices
1638 CALL timeset(routinen, handle)
1642 nrow_local_send =
SIZE(source%local_data, 1)
1643 ncol_local_send =
SIZE(source%local_data, 2)
1644 ALLOCATE (info%send_buf(nrow_local_send*ncol_local_send))
1646 DO j = 1, ncol_local_send
1647 DO i = 1, nrow_local_send
1649 info%send_buf(k) = source%local_data(i, j)
1653 NULLIFY (recv_dist, send_dist)
1654 NULLIFY (recv_col_indices, recv_row_indices, send_col_indices, send_row_indices)
1657 global_size = para_env%num_pe
1658 global_rank = para_env%mepos
1664 IF (
ASSOCIATED(destination%matrix_struct))
THEN
1665 recv_dist => destination%matrix_struct
1666 recv_rank = recv_dist%para_env%mepos
1671 IF (
ASSOCIATED(source%matrix_struct))
THEN
1672 send_dist => source%matrix_struct
1673 send_rank = send_dist%para_env%mepos
1679 ALLOCATE (all_ranks(0:global_size - 1))
1681 CALL para_env%allgather(send_rank, all_ranks)
1682 IF (
ASSOCIATED(recv_dist))
THEN
1683 ALLOCATE (source2global(0:count(all_ranks /=
mp_proc_null) - 1))
1684 DO i = 0, global_size - 1
1686 source2global(all_ranks(i)) = i
1691 CALL para_env%allgather(recv_rank, all_ranks)
1692 IF (
ASSOCIATED(send_dist))
THEN
1693 ALLOCATE (dest2global(0:count(all_ranks /=
mp_proc_null) - 1))
1694 DO i = 0, global_size - 1
1696 dest2global(all_ranks(i)) = i
1700 DEALLOCATE (all_ranks)
1707 IF (global_rank == 0)
THEN
1709 CALL para_env%irecv(src_block,
mp_any_source, recv_req(1), tag=src_tag)
1710 CALL para_env%irecv(dest_block,
mp_any_source, recv_req(2), tag=dest_tag)
1711 CALL para_env%irecv(src_num_pe,
mp_any_source, recv_req(3), tag=src_tag)
1712 CALL para_env%irecv(dest_num_pe,
mp_any_source, recv_req(4), tag=dest_tag)
1715 IF (
ASSOCIATED(send_dist))
THEN
1716 IF ((send_rank == 0))
THEN
1718 src_block_tmp = [send_dist%nrow_block, send_dist%ncol_block]
1719 CALL para_env%isend(src_block_tmp, 0, send_req(1), tag=src_tag)
1720 CALL para_env%isend(send_dist%context%num_pe, 0, send_req(2), tag=src_tag)
1724 IF (
ASSOCIATED(recv_dist))
THEN
1725 IF ((recv_rank == 0))
THEN
1726 dest_block_tmp = [recv_dist%nrow_block, recv_dist%ncol_block]
1727 CALL para_env%isend(dest_block_tmp, 0, send_req(3), tag=dest_tag)
1728 CALL para_env%isend(recv_dist%context%num_pe, 0, send_req(4), tag=dest_tag)
1732 IF (global_rank == 0)
THEN
1735 ALLOCATE (info%src_blacs2mpi(0:src_num_pe(1) - 1, 0:src_num_pe(2) - 1), &
1736 dest_blacs2mpi(0:dest_num_pe(1) - 1, 0:dest_num_pe(2) - 1) &
1738 CALL para_env%irecv(info%src_blacs2mpi,
mp_any_source, recv_req(5), tag=src_tag)
1739 CALL para_env%irecv(dest_blacs2mpi,
mp_any_source, recv_req(6), tag=dest_tag)
1742 IF (
ASSOCIATED(send_dist))
THEN
1743 IF ((send_rank == 0))
THEN
1744 CALL para_env%isend(send_dist%context%blacs2mpi(:, :), 0, send_req(5), tag=src_tag)
1748 IF (
ASSOCIATED(recv_dist))
THEN
1749 IF ((recv_rank == 0))
THEN
1750 CALL para_env%isend(recv_dist%context%blacs2mpi(:, :), 0, send_req(6), tag=dest_tag)
1754 IF (global_rank == 0)
THEN
1759 CALL para_env%bcast(src_block, 0)
1760 CALL para_env%bcast(dest_block, 0)
1761 CALL para_env%bcast(src_num_pe, 0)
1762 CALL para_env%bcast(dest_num_pe, 0)
1763 info%src_num_pe(1:2) = src_num_pe(1:2)
1764 info%nblock_src(1:2) = src_block(1:2)
1765 IF (global_rank /= 0)
THEN
1766 ALLOCATE (info%src_blacs2mpi(0:src_num_pe(1) - 1, 0:src_num_pe(2) - 1), &
1767 dest_blacs2mpi(0:dest_num_pe(1) - 1, 0:dest_num_pe(2) - 1) &
1770 CALL para_env%bcast(info%src_blacs2mpi, 0)
1771 CALL para_env%bcast(dest_blacs2mpi, 0)
1773 recv_size = dest_num_pe(1)*dest_num_pe(2)
1774 send_size = src_num_pe(1)*src_num_pe(2)
1775 info%send_size = send_size
1794 IF (
ASSOCIATED(recv_dist))
THEN
1796 col_indices=recv_col_indices &
1798 info%recv_col_indices => recv_col_indices
1799 info%recv_row_indices => recv_row_indices
1800 nrow_block_src = src_block(1)
1801 ncol_block_src = src_block(2)
1802 ALLOCATE (recv_count(0:send_size - 1), info%recv_disp(0:send_size - 1), info%recv_request(0:send_size - 1))
1805 nrow_local_recv = recv_dist%nrow_locals(recv_dist%context%mepos(1))
1806 ncol_local_recv = recv_dist%ncol_locals(recv_dist%context%mepos(2))
1807 info%nlocal_recv(1) = nrow_local_recv
1808 info%nlocal_recv(2) = ncol_local_recv
1810 ALLOCATE (src_p(nrow_local_recv), src_q(ncol_local_recv))
1811 DO i = 1, nrow_local_recv
1814 src_p(i) = mod(((recv_row_indices(i) - 1)/nrow_block_src), src_num_pe(1))
1816 DO j = 1, ncol_local_recv
1818 src_q(j) = mod(((recv_col_indices(j) - 1)/ncol_block_src), src_num_pe(2))
1822 DO q = 0, src_num_pe(2) - 1
1823 ncols = count(src_q == q)
1824 DO p = 0, src_num_pe(1) - 1
1825 nrows = count(src_p == p)
1827 recv_count(info%src_blacs2mpi(p, q)) = nrows*ncols
1830 DEALLOCATE (src_p, src_q)
1834 ALLOCATE (info%recv_buf(sum(recv_count(:))))
1835 info%recv_disp(0) = 0
1836 DO i = 1, send_size - 1
1837 info%recv_disp(i) = info%recv_disp(i - 1) + recv_count(i - 1)
1841 DO k = 0, send_size - 1
1842 IF (recv_count(k) > 0)
THEN
1843 CALL para_env%irecv(info%recv_buf(info%recv_disp(k) + 1:info%recv_disp(k) + recv_count(k)), &
1844 source2global(k), info%recv_request(k))
1847 DEALLOCATE (source2global)
1851 IF (
ASSOCIATED(send_dist))
THEN
1853 col_indices=send_col_indices &
1855 nrow_block_dest = dest_block(1)
1856 ncol_block_dest = dest_block(2)
1857 ALLOCATE (send_count(0:recv_size - 1), send_disp(0:recv_size - 1), info%send_request(0:recv_size - 1))
1860 nrow_local_send = send_dist%nrow_locals(send_dist%context%mepos(1))
1861 ncol_local_send = send_dist%ncol_locals(send_dist%context%mepos(2))
1865 ALLOCATE (dest_p(nrow_local_send), dest_q(ncol_local_send))
1867 DO i = 1, nrow_local_send
1869 dest_p(i) = mod(((send_row_indices(i) - 1)/nrow_block_dest), dest_num_pe(1))
1871 DO j = 1, ncol_local_send
1872 dest_q(j) = mod(((send_col_indices(j) - 1)/ncol_block_dest), dest_num_pe(2))
1876 DO q = 0, dest_num_pe(2) - 1
1877 ncols = count(dest_q == q)
1878 DO p = 0, dest_num_pe(1) - 1
1879 nrows = count(dest_p == p)
1880 send_count(dest_blacs2mpi(p, q)) = nrows*ncols
1883 DEALLOCATE (dest_p, dest_q)
1886 ALLOCATE (info%send_buf(sum(send_count(:))))
1888 DO k = 1, recv_size - 1
1889 send_disp(k) = send_disp(k - 1) + send_count(k - 1)
1894 DO j = 1, ncol_local_send
1896 dest_q_j = mod(((send_col_indices(j) - 1)/ncol_block_dest), dest_num_pe(2))
1897 DO i = 1, nrow_local_send
1898 dest_p_i = mod(((send_row_indices(i) - 1)/nrow_block_dest), dest_num_pe(1))
1899 mpi_rank = dest_blacs2mpi(dest_p_i, dest_q_j)
1900 send_count(mpi_rank) = send_count(mpi_rank) + 1
1901 info%send_buf(send_disp(mpi_rank) + send_count(mpi_rank)) = source%local_data(i, j)
1906 DO k = 0, recv_size - 1
1907 IF (send_count(k) > 0)
THEN
1908 CALL para_env%isend(info%send_buf(send_disp(k) + 1:send_disp(k) + send_count(k)), &
1909 dest2global(k), info%send_request(k))
1912 DEALLOCATE (send_count, send_disp, dest2global)
1914 DEALLOCATE (dest_blacs2mpi)
1918 CALL timestop(handle)
1931 CHARACTER(LEN=*),
PARAMETER :: routinen =
'cp_fm_finish_copy_general'
1933 INTEGER :: handle, i, j, k, mpi_rank, send_size, &
1935 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: recv_count
1936 INTEGER,
DIMENSION(2) :: nblock_src, nlocal_recv, src_num_pe
1937 INTEGER,
DIMENSION(:),
POINTER :: recv_col_indices, recv_row_indices
1939 CALL timeset(routinen, handle)
1944 DO j = 1,
SIZE(destination%local_data, 2)
1945 DO i = 1,
SIZE(destination%local_data, 1)
1947 destination%local_data(i, j) = info%send_buf(k)
1950 DEALLOCATE (info%send_buf)
1953 send_size = info%send_size
1954 nlocal_recv(1:2) = info%nlocal_recv(:)
1955 nblock_src(1:2) = info%nblock_src(:)
1956 src_num_pe(1:2) = info%src_num_pe(:)
1957 recv_col_indices => info%recv_col_indices
1958 recv_row_indices => info%recv_row_indices
1963 ALLOCATE (recv_count(0:send_size - 1))
1967 DO j = 1, nlocal_recv(2)
1968 src_q_j = mod(((recv_col_indices(j) - 1)/nblock_src(2)), src_num_pe(2))
1969 DO i = 1, nlocal_recv(1)
1970 src_p_i = mod(((recv_row_indices(i) - 1)/nblock_src(1)), src_num_pe(1))
1971 mpi_rank = info%src_blacs2mpi(src_p_i, src_q_j)
1972 recv_count(mpi_rank) = recv_count(mpi_rank) + 1
1973 destination%local_data(i, j) = info%recv_buf(info%recv_disp(mpi_rank) + recv_count(mpi_rank))
1976 DEALLOCATE (recv_count, info%recv_disp, info%recv_request, info%recv_buf, info%src_blacs2mpi)
1978 NULLIFY (info%recv_col_indices, &
1979 info%recv_row_indices)
1983 CALL timestop(handle)
2197 INTEGER,
INTENT(IN) :: unit
2198 INTEGER,
INTENT(IN),
OPTIONAL :: ncol
2200 CHARACTER(LEN=*),
PARAMETER :: routinen =
'cp_fm_write_unformatted'
2202 INTEGER :: handle, j, max_block, &
2203 ncol_global, nrow_global
2205#if defined(__parallel)
2206 INTEGER :: i, i_block, icol_local, &
2208 iprow, irow_local, &
2211 INTEGER,
DIMENSION(9) :: desc
2212 REAL(kind=
dp),
DIMENSION(:),
POINTER :: vecbuf
2213 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: newdat
2215 INTEGER,
EXTERNAL :: numroc
2218 CALL timeset(routinen, handle)
2219 CALL cp_fm_get_info(fm, nrow_global=nrow_global, ncol_global=ncol_global, ncol_block=max_block, &
2222 IF (
PRESENT(ncol))
THEN
2223 cpassert(ncol >= 0 .AND. ncol <= ncol_global)
2227#if defined(__parallel)
2228 num_pe = para_env%num_pe
2229 mepos = para_env%mepos
2233 CALL ictxt_loc%gridinit(para_env,
'R', 1, num_pe)
2234 CALL descinit(desc, nrow_global, ncol_global, rb, max_block, 0, 0, ictxt_loc%get_handle(), nrow_global, info)
2236 associate(nprow => ictxt_loc%num_pe(1), npcol => ictxt_loc%num_pe(2), &
2237 myprow => ictxt_loc%mepos(1), mypcol => ictxt_loc%mepos(2))
2238 in = numroc(ncol_global, max_block, mypcol, 0, npcol)
2240 ALLOCATE (newdat(nrow_global, max(1, in)))
2243 CALL pdgemr2d(nrow_global, ncol_global, fm%local_data, 1, 1, &
2244 fm%matrix_struct%descriptor, &
2245 newdat, 1, 1, desc, ictxt_loc%get_handle())
2247 ALLOCATE (vecbuf(nrow_global*max_block))
2248 vecbuf = huge(1.0_dp)
2250 DO i = 1, ncol_global, max(max_block, 1)
2251 i_block = min(max_block, ncol_global - i + 1)
2252 CALL infog2l(1, i, desc, nprow, npcol, myprow, mypcol, &
2253 irow_local, icol_local, iprow, ipcol)
2254 IF (ipcol == mypcol)
THEN
2256 vecbuf((j - 1)*nrow_global + 1:nrow_global*j) = newdat(:, icol_local + j - 1)
2260 IF (ipcol == 0)
THEN
2263 IF (ipcol == mypcol)
THEN
2264 CALL para_env%send(vecbuf(:), 0, tag)
2266 IF (mypcol == 0)
THEN
2267 CALL para_env%recv(vecbuf(:), ipcol, tag)
2273 WRITE (unit) vecbuf((j - 1)*nrow_global + 1:nrow_global*j)
2281 CALL ictxt_loc%gridexit()
2288 DO j = 1, ncol_global
2289 WRITE (unit) fm%local_data(:, j)
2294 CALL timestop(handle)
2307 INTEGER,
INTENT(IN) :: unit
2308 CHARACTER(LEN=*),
INTENT(IN),
OPTIONAL ::
header, value_format
2310 CHARACTER(LEN=*),
PARAMETER :: routinen =
'cp_fm_write_formatted'
2312 CHARACTER(LEN=21) :: my_value_format
2313 INTEGER :: handle, i, j, max_block, &
2314 ncol_global, nrow_global
2315 TYPE(mp_para_env_type),
POINTER :: para_env
2316#if defined(__parallel)
2317 INTEGER :: i_block, icol_local, &
2319 iprow, irow_local, &
2320 mepos, num_pe, rb, tag, k, &
2322 INTEGER,
DIMENSION(9) :: desc
2323 REAL(kind=dp),
DIMENSION(:),
POINTER :: vecbuf
2324 REAL(kind=dp),
DIMENSION(:, :),
POINTER :: newdat
2325 TYPE(cp_blacs_type) :: ictxt_loc
2326 INTEGER,
EXTERNAL :: numroc
2329 CALL timeset(routinen, handle)
2330 CALL cp_fm_get_info(fm, nrow_global=nrow_global, ncol_global=ncol_global, ncol_block=max_block, &
2333 IF (
PRESENT(value_format))
THEN
2334 cpassert(len_trim(adjustl(value_format)) < 11)
2335 my_value_format =
"(I10, I10, "//trim(adjustl(value_format))//
")"
2337 my_value_format =
"(I10, I10, ES24.12)"
2342 WRITE (unit,
"(A2, A8, A10, A24)")
"#",
"Row",
"Column", adjustl(
"Value")
2345#if defined(__parallel)
2346 num_pe = para_env%num_pe
2347 mepos = para_env%mepos
2351 CALL ictxt_loc%gridinit(para_env,
'R', 1, num_pe)
2352 CALL descinit(desc, nrow_global, ncol_global, rb, max_block, 0, 0, ictxt_loc%get_handle(), nrow_global, info)
2354 associate(nprow => ictxt_loc%num_pe(1), npcol => ictxt_loc%num_pe(2), &
2355 myprow => ictxt_loc%mepos(1), mypcol => ictxt_loc%mepos(2))
2356 in = numroc(ncol_global, max_block, mypcol, 0, npcol)
2358 ALLOCATE (newdat(nrow_global, max(1, in)))
2361 CALL pdgemr2d(nrow_global, ncol_global, fm%local_data, 1, 1, &
2362 fm%matrix_struct%descriptor, &
2363 newdat, 1, 1, desc, ictxt_loc%get_handle())
2365 ALLOCATE (vecbuf(nrow_global*max_block))
2366 vecbuf = huge(1.0_dp)
2370 DO i = 1, ncol_global, max(max_block, 1)
2371 i_block = min(max_block, ncol_global - i + 1)
2372 CALL infog2l(1, i, desc, nprow, npcol, myprow, mypcol, &
2373 irow_local, icol_local, iprow, ipcol)
2374 IF (ipcol == mypcol)
THEN
2376 vecbuf((j - 1)*nrow_global + 1:nrow_global*j) = newdat(:, icol_local + j - 1)
2380 IF (ipcol == 0)
THEN
2383 IF (ipcol == mypcol)
THEN
2384 CALL para_env%send(vecbuf(:), 0, tag)
2386 IF (mypcol == 0)
THEN
2387 CALL para_env%recv(vecbuf(:), ipcol, tag)
2393 DO k = (j - 1)*nrow_global + 1, nrow_global*j
2394 WRITE (unit=unit, fmt=my_value_format) irow, icol, vecbuf(k)
2396 IF (irow > nrow_global)
THEN
2408 CALL ictxt_loc%gridexit()
2415 DO j = 1, ncol_global
2416 DO i = 1, nrow_global
2417 WRITE (unit=unit, fmt=my_value_format) i, j, fm%local_data(i, j)
2423 CALL timestop(handle)